ویکیفەرھەنگ
ckbwiktionary
https://ckb.wiktionary.org/wiki/%D9%88%DB%8C%DA%A9%DB%8C%D9%81%DB%95%D8%B1%DA%BE%DB%95%D9%86%DA%AF:%D8%AF%DB%95%D8%B3%D8%AA%D9%BE%DB%8E%DA%A9
MediaWiki 1.47.0-wmf.15
case-sensitive
میدیا
تایبەت
وتووێژ
بەکارھێنەر
لێدوانی بەکارھێنەر
ویکیفەرھەنگ
لێدوانی ویکیفەرھەنگ
پەڕگە
وتووێژی پەڕگە
میدیاویکی
وتووێژی میدیاویکی
داڕێژە
وتووێژی داڕێژە
یارمەتی
وتووێژی یارمەتی
پۆل
وتووێژی پۆل
TimedText
TimedText talk
مۆدیوول
لێدوانی مۆدیوول
Event
Event talk
مۆدیوول:category tree
828
19
36931
36784
2026-08-18T00:04:03Z
Ghybu
12
بەپێی زمان (by language)
36931
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
--local words = split(title_text, " ", true)
--for i = #words - 1, 1, -1 do
-- local lang = getByCanonicalName(concat(words, " ", 1, i))
-- if lang then
-- return lang, concat(words, " ", i + 1)
-- end
--end
local label, langname = title_text:match("^(.-) بە (.+)$")
local lang = getByCanonicalName(langname)
if lang then
return lang, label
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"ئەم پۆلە لە داری پۆلی ویکیفەرھەنگدا پێناسە نەکراوە.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: left; clear: both; margin: 0 1em .5em 0; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s دراوەی پۆل دەستکاری بکە]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"دوایین دەستکاری و گۆڕانکارییەکانی تری پەڕەکانی نێو «%s»\">دوایین گۆڕانکارییەکان</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("reconstructed") then
namespace = namespace .. "Reconstruction"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "Appendix"
end
end
elseif info.label:match("templates") then
namespace = namespace .. "داڕێژە"
elseif info.label:match("modules") then
namespace = namespace .. "مۆدیوول"
elseif info.label:match("^Wiktionary") or info.label:match("^Pages") then
namespace = ""
end
return ([=[
{| id="newest-and-oldest-pages" class="wikitable mw-collapsible mw-collapsed" style="float: left; clear: both; margin: 0 1em .5em 0;"
! نوێترین و کۆنترین پەڕەکان
|-
| id="recent-additions" style="font-size:0.9em;" | '''نوێترین پەڕەکان بەپێی کۆتا [[mw:Manual:Categorylinks table#cl_timestamp|نوێکردنەوەی بەستەری پۆلەکە]] ڕیز کراون:'''
%s
|-
| id="oldest-pages" style="font-size:0.9em;" | '''کۆنترین پەڕەکان بەپێی کۆتا دەستکاری ڕیز کراون:'''
%s
|}]=]):format(
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=categoryadd
order=descending]=]
):format(current_title.text, namespace)
),
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=lastedit
order=ascending]=]
):format(current_title.text, namespace)
)
)
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^پۆل:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "پۆل:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[:%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("For more information, see [[%s]]."):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "پۆل:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[:%s]]: %s"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^پۆل:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[پۆل:%s|%s]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, ("[[%s|%s]]"):format(umbrella, sortkey))
else
insert(categories, ("[[پۆل:%s|%s]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "template" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[پۆل:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[پۆل:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[پۆل:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[پۆل:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "داڕێژە:auto cat" then
insert(categories, "[[پۆل:Categories calling Template:auto cat]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[پۆل:Huge categories]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[پۆل:ئەو پۆلانەی کە لە داری پۆلەکەدا پێناسە نەکراون]]")
insert(categories, totalPages == 0 and "[[پۆل:پۆلە واڵاکان]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[پۆل:Categories with incorrect names]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:پۆل:%s]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[پۆل:پۆلە واڵاکان]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: left;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above).
--if not hugeCategory then
-- insert(boxes, show_pagelist(current))
--end
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
-- insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^Thesaurus:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "terms" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("بەپێی زمان (.+)")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(ئەم داڕێژە پێویستە لەسەر پەڕەکانی بۆشاییناوی [[:en:Help:Namespaces#Category|پۆل:]] بەکاربھێنرێت.)"
elseif namespace ~= 14 then -- Category
error("ئەم داڕێژە/مۆدیوولە دەکرێ تەنیا لەسەر پەڕەکانی بۆشاییناوی [[mw:Help:Namespaces#Category|پۆل:]] بەکاربھێنرێت.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
es82p4d0pgo52y2mxchm1pip14v6qga
36940
36931
2026-08-18T01:26:31Z
Ghybu
12
پووچەڵکردنەوەی پێداچوونەوەی [[Special:Diff/36931|36931]] لە لایەن [[Special:Contributions/Ghybu|Ghybu]] ([[User talk:Ghybu|لێدوان]])
36940
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
--local words = split(title_text, " ", true)
--for i = #words - 1, 1, -1 do
-- local lang = getByCanonicalName(concat(words, " ", 1, i))
-- if lang then
-- return lang, concat(words, " ", i + 1)
-- end
--end
local label, langname = title_text:match("^(.-) بە (.+)$")
local lang = getByCanonicalName(langname)
if lang then
return lang, label
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"ئەم پۆلە لە داری پۆلی ویکیفەرھەنگدا پێناسە نەکراوە.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: left; clear: both; margin: 0 1em .5em 0; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s دراوەی پۆل دەستکاری بکە]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"دوایین دەستکاری و گۆڕانکارییەکانی تری پەڕەکانی نێو «%s»\">دوایین گۆڕانکارییەکان</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("reconstructed") then
namespace = namespace .. "Reconstruction"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "Appendix"
end
end
elseif info.label:match("templates") then
namespace = namespace .. "داڕێژە"
elseif info.label:match("modules") then
namespace = namespace .. "مۆدیوول"
elseif info.label:match("^Wiktionary") or info.label:match("^Pages") then
namespace = ""
end
return ([=[
{| id="newest-and-oldest-pages" class="wikitable mw-collapsible mw-collapsed" style="float: left; clear: both; margin: 0 1em .5em 0;"
! نوێترین و کۆنترین پەڕەکان
|-
| id="recent-additions" style="font-size:0.9em;" | '''نوێترین پەڕەکان بەپێی کۆتا [[mw:Manual:Categorylinks table#cl_timestamp|نوێکردنەوەی بەستەری پۆلەکە]] ڕیز کراون:'''
%s
|-
| id="oldest-pages" style="font-size:0.9em;" | '''کۆنترین پەڕەکان بەپێی کۆتا دەستکاری ڕیز کراون:'''
%s
|}]=]):format(
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=categoryadd
order=descending]=]
):format(current_title.text, namespace)
),
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=lastedit
order=ascending]=]
):format(current_title.text, namespace)
)
)
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^پۆل:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "پۆل:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[:%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("For more information, see [[%s]]."):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "پۆل:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[:%s]]: %s"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^پۆل:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[پۆل:%s|%s]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, ("[[%s|%s]]"):format(umbrella, sortkey))
else
insert(categories, ("[[پۆل:%s|%s]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "template" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[پۆل:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[پۆل:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[پۆل:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[پۆل:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "داڕێژە:auto cat" then
insert(categories, "[[پۆل:Categories calling Template:auto cat]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[پۆل:Huge categories]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[پۆل:ئەو پۆلانەی کە لە داری پۆلەکەدا پێناسە نەکراون]]")
insert(categories, totalPages == 0 and "[[پۆل:پۆلە واڵاکان]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[پۆل:Categories with incorrect names]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:پۆل:%s]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[پۆل:پۆلە واڵاکان]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: left;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above).
--if not hugeCategory then
-- insert(boxes, show_pagelist(current))
--end
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
-- insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^Thesaurus:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "terms" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("(.+) by language$")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(ئەم داڕێژە پێویستە لەسەر پەڕەکانی بۆشاییناوی [[:en:Help:Namespaces#Category|پۆل:]] بەکاربھێنرێت.)"
elseif namespace ~= 14 then -- Category
error("ئەم داڕێژە/مۆدیوولە دەکرێ تەنیا لەسەر پەڕەکانی بۆشاییناوی [[mw:Help:Namespaces#Category|پۆل:]] بەکاربھێنرێت.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
0lncvn4qup3fuhj4huf9jspmvfh9hj8
36943
36940
2026-08-18T01:31:38Z
Ghybu
12
پووچەڵکردنەوەی پێداچوونەوەی [[Special:Diff/36940|36940]] لە لایەن [[Special:Contributions/Ghybu|Ghybu]] ([[User talk:Ghybu|لێدوان]])
36943
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
--local words = split(title_text, " ", true)
--for i = #words - 1, 1, -1 do
-- local lang = getByCanonicalName(concat(words, " ", 1, i))
-- if lang then
-- return lang, concat(words, " ", i + 1)
-- end
--end
local label, langname = title_text:match("^(.-) بە (.+)$")
local lang = getByCanonicalName(langname)
if lang then
return lang, label
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"ئەم پۆلە لە داری پۆلی ویکیفەرھەنگدا پێناسە نەکراوە.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: left; clear: both; margin: 0 1em .5em 0; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s دراوەی پۆل دەستکاری بکە]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"دوایین دەستکاری و گۆڕانکارییەکانی تری پەڕەکانی نێو «%s»\">دوایین گۆڕانکارییەکان</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("reconstructed") then
namespace = namespace .. "Reconstruction"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "Appendix"
end
end
elseif info.label:match("templates") then
namespace = namespace .. "داڕێژە"
elseif info.label:match("modules") then
namespace = namespace .. "مۆدیوول"
elseif info.label:match("^Wiktionary") or info.label:match("^Pages") then
namespace = ""
end
return ([=[
{| id="newest-and-oldest-pages" class="wikitable mw-collapsible mw-collapsed" style="float: left; clear: both; margin: 0 1em .5em 0;"
! نوێترین و کۆنترین پەڕەکان
|-
| id="recent-additions" style="font-size:0.9em;" | '''نوێترین پەڕەکان بەپێی کۆتا [[mw:Manual:Categorylinks table#cl_timestamp|نوێکردنەوەی بەستەری پۆلەکە]] ڕیز کراون:'''
%s
|-
| id="oldest-pages" style="font-size:0.9em;" | '''کۆنترین پەڕەکان بەپێی کۆتا دەستکاری ڕیز کراون:'''
%s
|}]=]):format(
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=categoryadd
order=descending]=]
):format(current_title.text, namespace)
),
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=lastedit
order=ascending]=]
):format(current_title.text, namespace)
)
)
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^پۆل:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "پۆل:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[:%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("For more information, see [[%s]]."):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "پۆل:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[:%s]]: %s"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^پۆل:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[پۆل:%s|%s]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, ("[[%s|%s]]"):format(umbrella, sortkey))
else
insert(categories, ("[[پۆل:%s|%s]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "template" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[پۆل:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[پۆل:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[پۆل:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[پۆل:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "داڕێژە:auto cat" then
insert(categories, "[[پۆل:Categories calling Template:auto cat]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[پۆل:Huge categories]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[پۆل:ئەو پۆلانەی کە لە داری پۆلەکەدا پێناسە نەکراون]]")
insert(categories, totalPages == 0 and "[[پۆل:پۆلە واڵاکان]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[پۆل:Categories with incorrect names]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:پۆل:%s]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[پۆل:پۆلە واڵاکان]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: left;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above).
--if not hugeCategory then
-- insert(boxes, show_pagelist(current))
--end
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
-- insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^Thesaurus:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "terms" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("بەپێی زمان (.+)")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(ئەم داڕێژە پێویستە لەسەر پەڕەکانی بۆشاییناوی [[:en:Help:Namespaces#Category|پۆل:]] بەکاربھێنرێت.)"
elseif namespace ~= 14 then -- Category
error("ئەم داڕێژە/مۆدیوولە دەکرێ تەنیا لەسەر پەڕەکانی بۆشاییناوی [[mw:Help:Namespaces#Category|پۆل:]] بەکاربھێنرێت.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
es82p4d0pgo52y2mxchm1pip14v6qga
36944
36943
2026-08-18T01:35:27Z
Ghybu
12
36944
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
--local words = split(title_text, " ", true)
--for i = #words - 1, 1, -1 do
-- local lang = getByCanonicalName(concat(words, " ", 1, i))
-- if lang then
-- return lang, concat(words, " ", i + 1)
-- end
--end
local label, langname = title_text:match("^(.-) بە (.+)$")
local lang = getByCanonicalName(langname)
if lang then
return lang, label
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"ئەم پۆلە لە داری پۆلی ویکیفەرھەنگدا پێناسە نەکراوە.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: left; clear: both; margin: 0 1em .5em 0; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s دراوەی پۆل دەستکاری بکە]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"دوایین دەستکاری و گۆڕانکارییەکانی تری پەڕەکانی نێو «%s»\">دوایین گۆڕانکارییەکان</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("reconstructed") then
namespace = namespace .. "Reconstruction"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "Appendix"
end
end
elseif info.label:match("templates") then
namespace = namespace .. "داڕێژە"
elseif info.label:match("modules") then
namespace = namespace .. "مۆدیوول"
elseif info.label:match("^Wiktionary") or info.label:match("^Pages") then
namespace = ""
end
return ([=[
{| id="newest-and-oldest-pages" class="wikitable mw-collapsible mw-collapsed" style="float: left; clear: both; margin: 0 1em .5em 0;"
! نوێترین و کۆنترین پەڕەکان
|-
| id="recent-additions" style="font-size:0.9em;" | '''نوێترین پەڕەکان بەپێی کۆتا [[mw:Manual:Categorylinks table#cl_timestamp|نوێکردنەوەی بەستەری پۆلەکە]] ڕیز کراون:'''
%s
|-
| id="oldest-pages" style="font-size:0.9em;" | '''کۆنترین پەڕەکان بەپێی کۆتا دەستکاری ڕیز کراون:'''
%s
|}]=]):format(
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=categoryadd
order=descending]=]
):format(current_title.text, namespace)
),
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=lastedit
order=ascending]=]
):format(current_title.text, namespace)
)
)
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^پۆل:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "پۆل:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[:%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("For more information, see [[%s]]."):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "پۆل:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[:%s]]: %s"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^پۆل:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[پۆل:%s|%s]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, ("[[%s|%s]]"):format(umbrella, sortkey))
else
insert(categories, ("[[پۆل:%s|%s]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "template" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[پۆل:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[پۆل:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[پۆل:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[پۆل:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "داڕێژە:auto cat" then
insert(categories, "[[پۆل:Categories calling Template:auto cat]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[پۆل:Huge categories]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[پۆل:ئەو پۆلانەی کە لە داری پۆلەکەدا پێناسە نەکراون]]")
insert(categories, totalPages == 0 and "[[پۆل:پۆلە واڵاکان]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[پۆل:Categories with incorrect names]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:پۆل:%s]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[پۆل:پۆلە واڵاکان]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: left;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above).
--if not hugeCategory then
-- insert(boxes, show_pagelist(current))
--end
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
-- insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^Thesaurus:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "terms" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("(.+) بەپێی زمان")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(ئەم داڕێژە پێویستە لەسەر پەڕەکانی بۆشاییناوی [[:en:Help:Namespaces#Category|پۆل:]] بەکاربھێنرێت.)"
elseif namespace ~= 14 then -- Category
error("ئەم داڕێژە/مۆدیوولە دەکرێ تەنیا لەسەر پەڕەکانی بۆشاییناوی [[mw:Help:Namespaces#Category|پۆل:]] بەکاربھێنرێت.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
2papq0onifznmty3rc0nf5vulhsq67d
مۆدیوول:category tree/poscatboiler
828
21
36933
36744
2026-08-18T00:29:54Z
Ghybu
12
بەپێی زمان (by language)
36933
Scribunto
text/plain
local lang_independent_data = require("Module:category tree/data")
local lang_specific_module = "Module:category tree/lang"
local lang_specific_module_prefix = lang_specific_module .. "/"
local family_specific_module = "Module:category tree/fam"
local family_specific_module_prefix = family_specific_module .. "/"
local labels_utilities_module = "Module:labels/utilities"
local template_parser_module = "Module:template parser"
local concat = table.concat
local dump = mw.dumpObject
local expand_template = require("Module:frame").expandTemplate
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local lcfirst = require("Module:string utilities").lcfirst
local list_to_set = require("Module:table").listToSet
local make_title = mw.title.makeTitle
local new_title = mw.title.new
local parse = require(template_parser_module).parse
local sparse_concat = require("Module:table").sparseConcat
local tostring = tostring
local type = type
local ucfirst = require("Module:string utilities").ucfirst
local uupper = require("Module:string utilities").upper
local function internal_error(msg)
error("Internal error: " .. msg)
end
local function get_lang(...)
local _get_lang = require("Module:languages").getByCode
function get_lang(...)
return _get_lang(...) or require("Module:languages/errorGetBy").code(...)
end
return get_lang(...)
end
local function get_script(...)
local _get_script = require("Module:scripts").getByCode
function get_script(code)
return _get_script(code) or require("Module:languages/error")(code, true, "script code")
end
return get_script(...)
end
-- Category object
local Category = {}
Category.__index = Category
function Category:get_originating_info()
local originating_info = ""
if self._info.originating_label then
originating_info = " (originating from label \"" .. self._info.originating_label .. "\" in module [[" .. self._info.originating_module .. "]])"
end
return originating_info
end
local valid_keys = list_to_set{"code", "label", "sc", "raw", "args", "also", "called_from_inside", "originating_label", "originating_module"}
function Category.new(info)
for key in pairs(info) do
if not valid_keys[key] then
internal_error("The parameter \"" .. key .. "\" was not recognized.")
end
end
local self = setmetatable({}, Category)
self._info = info
if not self._info.label then
internal_error("No label was specified.")
end
self:initCommon()
if not self._data then
internal_error("The " .. (self._info.raw and "raw " or "") .. "label \"" .. self._info.label .. "\" does not exist" .. self:get_originating_info() .. ".")
end
return self
end
function Category:initCommon()
local function patch_args(args)
-- This fixes the issue with Scribunto automatically converting keys
-- in a table as numbers to strings, which in turn causes a circular
-- error for having argument parameter names as numbers as strings.
if type(args) ~= "table" then
return args
end
local new_args = {}
for k, v in pairs(args) do
if type(k) == "string" and string.len(k) < 10 and not string.match(k, "^0") and string.match(k, "^%d+$") then
new_args[tonumber(k)] = patch_args(v)
else
new_args[k] = patch_args(v)
end
end
return new_args
end
local args_handled = false
if self._info.raw then
-- Check if the category exists
local raw_categories = lang_independent_data["RAW_CATEGORIES"]
self._data = raw_categories[self._info.label]
if self._data then
if self._data.lang then
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
else
-- Go through raw handlers
local data = {
category = self._info.label,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["RAW_HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
if self._data then
-- Update the label if the handler specified a canonical name for it.
if self._data.canonical_name then
self._info.canonical_name = self._data.canonical_name
end
if self._data.lang then
if type(self._data.lang) ~= "string" then
internal_error("Received non-string value " .. dump(self._data.lang) .. " for self._data.lang, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
if type(self._data.sc) ~= "string" then
internal_error("Received non-string value " .. dump(self._data.sc) .. " for self._data.sc, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
end
end
else
-- Already parsed into language + label
if self._info.code then
self._lang = get_lang(self._info.code)
else
self._lang = nil
end
if self._info.sc then
self._sc = get_script(self._info.sc)
else
self._sc = nil
end
self._info.orig_label = self._info.label
if not self._lang then
-- Umbrella categories without a preceding language always begin with a capital letter, but the actual label may be
-- lowercase (cf. [[:Category:Nouns by language]] with label 'nouns' with per-language [[:Category:English nouns]];
-- but [[:Category:Reddit slang by language]] with label 'Reddit slang' with per-language
-- [[:Category:English Reddit slang]]). Since the label is almost always lowercase, we lowercase it for umbrella
-- categories, storing the original into `orig_label`, and correct it later if needed.
self._info.label = lcfirst(self._info.label)
end
-- First, check lang-specific labels and handlers if this is not an umbrella category.
if self._lang then
local objects_with_modules = require(lang_specific_module)
local obj, seen = self._lang, {}
local object_specific_module_prefix = lang_specific_module_prefix
local is_family = false
repeat
if objects_with_modules[obj:getCode()] then
local module = object_specific_module_prefix .. obj:getCode()
local labels_and_handlers = require(module)
if labels_and_handlers.LABELS then
self._data = labels_and_handlers.LABELS[self._info.label]
if self._data then
if not is_family and self._data.umbrella == nil and self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
end
end
if not self._data and labels_and_handlers.HANDLERS then
for _, handler in ipairs(labels_and_handlers.HANDLERS) do
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
self._data, args_handled = handler(data)
if self._data then
if not is_family and self._data.umbrella == nil and
self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
break
end
end
end
if self._data then
break
end
end
seen[obj:getCode()] = true
obj = obj:getFamily()
if not is_family then
is_family = true
object_specific_module_prefix = family_specific_module_prefix
objects_with_modules = require(family_specific_module)
end
until not obj or seen[obj:getCode()]
end
local function fetch_label_data(labels)
self._data = labels[self._info.label]
-- See comment above about uppercase- vs. lowercase-initial labels, which are indistinguishable
-- in umbrella categories.
if not self._data then
self._data = labels[self._info.orig_label]
if self._data then
self._info.label = self._info.orig_label
end
end
end
-- Then check lang-independent labels.
if not self._data then
-- lang_independent_data.LABELS should always exist.
fetch_label_data(lang_independent_data.LABELS)
if not self._data and not self._lang then
-- Check family-specific labels for umbrella label.
local families_with_modules = require(family_specific_module)
for famcode, _ in pairs(families_with_modules) do
local module = family_specific_module_prefix .. famcode
local labels_and_handlers = require(module)
if labels_and_handlers.LABELS then
fetch_label_data(labels_and_handlers.LABELS)
if self._data then
self._data.module = self._data.module or module
break
end
end
end
end
end
-- Then check lang-independent handlers.
if not self._data then
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
if not self._data and not self._lang then
-- Check family-specific labels for umbrella handler.
local families_with_modules = require(family_specific_module)
for famcode, _ in pairs(families_with_modules) do
local module = family_specific_module_prefix .. famcode
local labels_and_handlers = require(module)
if labels_and_handlers.HANDLERS then
for _, handler in ipairs(labels_and_handlers.HANDLERS) do
local data = {
label = self._info.label,
sc = self._sc,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
self._data, args_handled = handler(data)
if self._data then
self._data.module = self._data.module or module
break
end
end
end
if self._data then
break
end
end
end
end
end
if not args_handled and self._data and self._info.args and next(self._info.args) then
local module_text = " (handled in [[" .. (self._data.module or "UNKNOWN").. "]])"
local args_text = {}
for k, v in pairs(self._info.args) do
insert(args_text, k .. "=" .. ((type(v) == "string" or type(v) == "number") and v or dump(v)))
end
error("poscatboiler label '" .. self._info.label .. "' " .. module_text .. " doesn't accept extra args " ..
concat(args_text, ", "))
end
if self._sc and not self._lang then
internal_error("Umbrella categories cannot have a script specified.")
end
end
function Category:convert_spec_to_string(desc)
if not desc then
return desc
end
local desc_type = type(desc)
if desc_type == "string" then
return desc
elseif desc_type == "number" then
return tostring(desc)
elseif not is_callable(desc) then
internal_error("`desc` must be a string, number, function, callable table or nil; received " .. dump(desc))
end
desc = desc {
lang = self._lang,
sc = self._sc,
label = self._info.label,
raw = self._info.raw,
}
if not desc then
return desc
end
desc_type = type(desc)
if desc_type == "string" then
return desc
end
internal_error("The value returned by `desc` must be a string or nil; received " .. dump(desc))
end
local function add_obj_args(args, obj, obj_type)
if obj then
args[obj_type .. "code"] = obj:getCode()
args[obj_type .. "name"] = obj:getCanonicalName()
args[obj_type .. "disp"] = obj:getDisplayForm()
args[obj_type .. "cat"] = obj:getCategoryName()
args[obj_type .. "link"] = obj:makeCategoryLink()
end
end
-- Expands `desc` like a template, passing values for specs like {{{langname}}}.
function Category:substitute_template_specs(desc)
-- This may end up happening twice but that's OK as the function is (usually) idempotent.
-- FIXME: Not idempotent if a preprocessed template returns wikicode.
desc = self:convert_spec_to_string(desc)
if not desc then
return nil
end
-- Populate the substitution arguments.
local args = {}
args.umbrella_msg = "ئەمە پۆلێکی گشتگیرە. ھیچ سەروشەیەکی فەرھەنگی تێدا نییە، بەڵکوو تەنیا پۆلەکانی تری تایبەت بە زمانی تێدایە، کە ئەوانیش چەمکە پەیوەندیدارەکان بەو زمانەیان تێدایە."
args.umbrella_meta_msg = "This is an umbrella metacategory, covering a general area such as \"lemmas\", \"names\" or \"terms by etymology\". It contains no dictionary entries, but holds only umbrella (\"by language\") categories covering specific subtopics, which in turn contain language-specific categories holding terms in a given language for that same topic."
add_obj_args(args, self._lang, "lang")
add_obj_args(args, self._sc, "sc")
return parse(desc, true):expand(args)
end
function Category:substitute_template_specs_in_args(args)
if not args then
return args
end
local pinfo = {}
for k, v in pairs(args) do
pinfo[self:substitute_template_specs(k)] = self:substitute_template_specs(v)
end
return pinfo
end
function Category:make_new(info)
info.originating_label = self._info.label
info.originating_module = self._data.module
info.called_from_inside = true
return Category.new(info)
end
function Category:getBreadcrumbName()
local ret
if self._lang or self._info.raw then
ret = self._data.breadcrumb or self._data.breadcrumb_and_first_sort_base
else
ret = self._data.umbrella and (self._data.umbrella.breadcrumb or self._data.umbrella.breadcrumb_and_first_sort_base)
end
if not ret then
ret = self._info.label
end
if type(ret) ~= "table" then
ret = {name = ret}
end
local name = self:substitute_template_specs(ret.name)
local nocap = ret.nocap
if self._sc then
name = name .. " in " .. self._sc:getDisplayForm()
end
return name, nocap
end
local function expand_toc_template_if(template)
local template_obj = new_title(template, 10)
if template_obj.exists then
return expand_template{title = template_obj.text}
end
return nil
end
-- Return the textual expansion of the first existing template among the given templates, first performing
-- substitutions on the template name such as replacing {{{langcode}}} with the current language's code (if any).
-- If no templates exist after expansion, or if nil is passed in, return nil. If a single string is passed in,
-- treat it like a one-element list consisting of that string.
function Category:get_template_text(templates)
if templates == nil then
return nil
elseif type(templates) ~= "table" then
templates = {templates}
end
for _, template in ipairs(templates) do
if template == false then
return false
end
template = self:substitute_template_specs(template)
return expand_toc_template_if(template)
end
return nil
end
function Category:getTOC(toc_type)
-- Type "none" means everything fits on a single page; in that case, display nothing.
if toc_type == "none" then
return nil
end
local templates, fallback_templates
-- If TOC type is "full" (more than 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template_full` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. look up and expand the `toc_template` templates (normal or umbrella, as above);
-- 3. do the default behavior, which is as follows:
-- 3a. look up a language-specific "full" template according to the current language (using English if there
-- is no current language);
-- 3b. look up a script-specific "full" template according to the first script of current language (using English
-- if there is no current language);
-- 3c. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 3d. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 3e. display nothing.
--
-- If TOC type is "normal" (between 200 and 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. do the default behavior, which is as follows:
-- 2a. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 2b. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 2c. display nothing.
local data_source
if self._lang or self._info.raw then
data_source = self._data
else
data_source = self._data.umbrella
end
if data_source then
if toc_type == "full" then
templates = data_source.toc_template_full
fallback_templates = data_source.toc_template
else
templates = data_source.toc_template
end
end
local text = self:get_template_text(templates)
if text then
return text
elseif text == false then
return nil
end
text = self:get_template_text(fallback_templates)
if text then
return text
elseif text == false then
return nil
end
local default_toc_templates_to_check = {}
local lang, sc = self:getCatfixInfo()
local langcode = lang and lang:getCode() or "en"
local sccode = sc and sc:getCode() or lang and lang:getScriptCodes()[1] or "Latn"
-- FIXME: What is toctemplateprefix used for?
local tocname = (self._data.toctemplateprefix or "") .. "categoryTOC"
if toc_type == "full" then
insert(default_toc_templates_to_check, ("%s-%s/full"):format(langcode, tocname))
insert(default_toc_templates_to_check, ("%s-%s/full"):format(sccode, tocname))
end
insert(default_toc_templates_to_check, ("%s-%s"):format(langcode, tocname))
insert(default_toc_templates_to_check, ("%s-%s"):format(sccode, tocname))
for _, toc_template in ipairs(default_toc_templates_to_check) do
local toc_template_text = expand_toc_template_if(toc_template)
if toc_template_text then
return toc_template_text
end
end
return nil
end
function Category:getInfo()
return self._info
end
function Category:getDataModule()
return self._data.module
end
function Category:canBeEmpty()
if self._lang or self._info.raw then
return self._data.can_be_empty
end
return self._data.umbrella and self._data.umbrella.can_be_empty
end
function Category:isHidden()
if self._lang or self._info.raw then
return self._data.hidden
end
return self._data.umbrella and self._data.umbrella.hidden
end
function Category:getCategoryName()
if self._info.raw then
return self._info.canonical_name or self._info.label
elseif self._lang then
local ret = self._info.label .. " بە " .. self._lang:getCanonicalName()
if self._sc then
ret = ret .. " in " .. self._sc:getDisplayForm()
end
return ucfirst(ret)
end
local ret = ucfirst(self._info.label)
if not (self._data.no_by_language or self._data.umbrella and self._data.umbrella.no_by_language) then
ret = ret .. " بەپێی زمان"
end
return ret
end
function Category:getTopright()
if self._lang or self._info.raw then
return self:substitute_template_specs(self._data.topright)
end
return self._data.umbrella and self:substitute_template_specs(self._data.umbrella.topright)
end
function Category:display_title(displaytitle, lang)
if type(displaytitle) == "string" then
displaytitle = self:substitute_template_specs(displaytitle)
else
displaytitle = displaytitle(self:getCategoryName(), lang)
end
mw.getCurrentFrame():callParserFunction("DISPLAYTITLE", "Category:" .. displaytitle)
end
function Category:get_labels_categorizing()
local m_labels_utilities = require(labels_utilities_module)
local pos_cat_labels, sense_cat_labels, use_tlb
pos_cat_labels = m_labels_utilities.find_labels_for_category(self._info.label, "pos", self._lang)
local sense_label = self._info.label:match("^(.*) terms$")
if sense_label then
use_tlb = true
else
sense_label = self._info.label:match("^terms with (.*) senses$")
end
if not sense_label then
return nil
end
sense_cat_labels = m_labels_utilities.find_labels_for_category(sense_label, "sense", self._lang)
if use_tlb then
return m_labels_utilities.format_labels_categorizing(pos_cat_labels, sense_cat_labels, self._lang)
end
local all_labels = pos_cat_labels
for k, v in pairs(sense_cat_labels) do
all_labels[k] = v
end
return m_labels_utilities.format_labels_categorizing(all_labels, nil, self._lang)
end
-- FIXME: this is clunky.
local function remove_lang_params(desc)
-- Simply remove a language name/code/category from the beginning of the string, but replace the language name
-- in the middle of the string with either "specific languages" or "specific-language" depending on whether the
-- language name appears to be an attributive qualifier of another noun or to stand by itself. This may be wrong,
-- in which case the category in question should supply its own umbrella description.
desc = desc:gsub("^{{{langname}}} ", "")
:gsub("{{{langname}}} %(", "specific languages (")
:gsub("{{{langname}}}([.,])", "specific languages%1")
:gsub("{{{langname}}} ", "specific-language ")
:gsub("{{{langdisp}}}", "specific languages")
:gsub("{{{langlink}}}", "specific languages")
return desc
end
function Category:getDescription(isChild)
-- Allows different text in the list of a category's children
local isChild = isChild == "child"
if self._lang or self._info.raw then
if not isChild and self._data.displaytitle then
self:display_title(self._data.displaytitle, self._lang)
end
if self._sc then
return self:getCategoryName() .. "."
end
local desc = self:substitute_template_specs(self._data.description)
if not desc then
return nil
elseif isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(self._data.preceding),
desc,
self:substitute_template_specs(self._data.additional),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
local umbrella = self._data.umbrella
if not isChild and umbrella and umbrella.displaytitle then
self:display_title(umbrella.displaytitle)
end
local desc = self:substitute_template_specs(umbrella and umbrella.description)
local has_umbrella_desc = not not desc
if not desc then
desc = self:convert_spec_to_string(self._data.description)
if desc then
desc = remove_lang_params(desc)
desc = lcfirst(desc)
desc = desc:gsub("%.$", "")
desc = "Categories with " .. desc .. "."
else
desc = "Categories with " .. self._info.label .. " in various specific languages."
end
desc = self:substitute_template_specs(desc)
end
if isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(umbrella and umbrella.preceding or not has_umbrella_desc and self._data.preceding),
desc,
self:substitute_template_specs(umbrella and umbrella.additional or not has_umbrella_desc and self._data.additional),
self:substitute_template_specs("{{{umbrella_msg}}}"),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
function Category:new_sortkey(sortkey)
local sortkey_type = type(sortkey)
if sortkey_type == "string" then
sortkey = uupper(sortkey)
elseif sortkey_type == "table" then
function sortkey:makeSortKey()
local sort_func = self.sort_func
if sort_func ~= nil then
return sort_func(self.sort_base)
end
local lang = self.lang
if lang == nil then
return self.sort_base
end
lang = get_lang(lang, nil, true)
if lang == nil then
return self.sort_base
end
local sc = self.sc
if sc ~= nil then
sc = get_script(sc)
end
return lang:makeSortKey(self.sort_base, sc)
end
end
return sortkey
end
function Category:inherit_spec(spec, parent_spec, substitute_result)
if spec == false then
return nil
end
local retval = spec or parent_spec
if substitute_result then
retval = self:substitute_template_specs(retval)
end
return retval
end
function Category:canonicalize_parents_children(cats, is_children, fallback_sort_base)
if not cats then
return nil
elseif type(cats) == "table" then
if cats.name or cats.module then
cats = {cats}
elseif #cats == 0 then
return nil
end
else
cats = {cats}
end
local ret = {}
for _, cat in ipairs(cats) do
if type(cat) ~= "table" or not cat.name and not cat.module then
cat = {name = cat}
end
insert(ret, cat)
end
local is_umbrella = not self._lang and not self._info.raw
local table_type = is_children and "extra_children" or "parents"
for i, cat in ipairs(ret) do
local raw
if self._info.raw or is_umbrella then
raw = not cat.is_label
else
raw = cat.raw
end
local lang = self:inherit_spec(cat.lang, not raw and self._info.code or nil, "substitute")
local sc = self:inherit_spec(cat.sc, not raw and self._info.sc or nil, "substitute")
-- Get the sortkey.
local sortkey = self:inherit_spec(cat.sort, i == 1 and fallback_sort_base and {sort_base = fallback_sort_base} or nil)
if type(sortkey) == "table" then
sortkey.sort_base = self:substitute_template_specs(sortkey.sort_base) or
internal_error("Missing .sort_base in '" .. table_type .. "' .sort table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
if sortkey.sort_func then
-- Not allowed to give a lang and/or script if sort_func is given.
local bad_spec = sortkey.lang and "lang" or sortkey.sc and "sc" or nil
if bad_spec then
internal_error("Cannot specify both ." .. bad_spec .. " and .sort_func in '" .. table_type ..
"' .sort table for '" .. self._info.label .. "' category entry in module '" ..
(self._data.module or "unknown") .. "'")
end
else
sortkey.lang = self:inherit_spec(sortkey.lang, lang, "substitute")
sortkey.sc = self:inherit_spec(sortkey.sc, sc, "substitute")
end
else
sortkey = self:substitute_template_specs(sortkey)
end
local name
if cat.module then
-- A reference to a category using another category tree module.
if not cat.args then
internal_error("Missing .args in '" .. table_type .. "' table with module=\"" .. cat.module .. "\" for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
end
name = require("Module:category tree/" .. cat.module).new(self:substitute_template_specs_in_args(cat.args))
else
name = cat.name
if not name then
internal_error("Missing .name in " .. (is_umbrella and "umbrella " or "") .. "'" .. table_type .. "' table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
elseif type(name) == "string" then -- otherwise, assume it's a category object and use it directly
name = self:substitute_template_specs(name)
if name:find("^Category:") then
-- It's a non-poscatboiler category name.
sortkey = sortkey or is_children and name:gsub("^Category:", "") or self:getCategoryName()
else
-- It's a label.
sortkey = sortkey or is_children and name or self._info.label
name = self:make_new{
label = name, code = lang, sc = sc,
raw = raw, args = self:substitute_template_specs_in_args(cat.args)
}
end
end
end
sortkey = sortkey or is_children and " " or self._info.label
ret[i] = {
name = name,
description = is_children and self:substitute_template_specs(cat.description) or nil,
sort = self:new_sortkey(sortkey)
}
end
return ret
end
function Category:getParents()
local is_umbrella, ret = not self._lang and not self._info.raw
if self._sc then
local parent1 = self:make_new{code = self._info.code, label = "terms in " .. self._sc:getCanonicalName() .. " script"}
local parent2 = self:make_new{code = self._info.code, label = self._info.label, raw = self._info.raw, args = self._info.args}
ret = {
{name = parent1, sort = self._sc:getCanonicalName()},
{name = parent2, sort = self._sc:getCanonicalName()},
}
else
local parents, fallback_sort_base
if is_umbrella then
parents = self._data.umbrella and self._data.umbrella.parents or self._data.umbrella_parents
fallback_sort_base = self._data.umbrella and self._data.umbrella.breadcrumb_and_first_sort_base or nil
else
parents = self._data.parents
fallback_sort_base = self._data.breadcrumb_and_first_sort_base
end
ret = self:canonicalize_parents_children(parents, nil, fallback_sort_base)
if not ret then
return nil
end
end
local self_cat = self:getCategoryName()
for _, parent in ipairs(ret) do
local parent_cat = parent.name.getCategoryName and parent.name:getCategoryName()
if self_cat == parent_cat then
internal_error(("Infinite loop would occur, as parent category '%s' is the same as the child category"):format(self_cat))
end
end
return ret
end
function Category:getChildren()
local is_umbrella = not self._lang and not self._info.raw
local children = self._data.children
local ret = {}
if not is_umbrella and children then
for _, child in ipairs(children) do
child = mw.clone(child)
if type(child) ~= "table" then
child = {name = child}
end
if not child.sort then
child.sort = child.name
end
-- FIXME, is preserving the script correct?
child.name = self:make_new{code = self._info.code, label = child.name, raw = child.raw, sc = self._info.sc}
insert(ret, child)
end
end
local extra_children
if is_umbrella then
extra_children = self._data.umbrella and self._data.umbrella.extra_children
else
extra_children = self._data.extra_children
end
extra_children = self:canonicalize_parents_children(extra_children, "children")
if extra_children then
for _, child in ipairs(extra_children) do
insert(ret, child)
end
end
return #ret > 0 and ret or nil
end
function Category:getUmbrella()
local umbrella = self._data.umbrella
if umbrella == false or self._info.raw or not self._lang or self._sc then
return nil
end
-- If `umbrella` is a string, use that; otherwise, use the label.
return self:make_new({label = type(umbrella) == "string" and umbrella or self._info.label})
end
function Category:getAppendix()
-- FIXME, this should be customizable.
local lang, label = self._lang, self._info.label
if self._info.raw or not (lang and label) then
return nil
end
local appendix = make_title(100, lang:getCanonicalName() .. " " .. label)
return appendix.exists and appendix.fullText or nil
end
function Category:getCatfixInfo()
if self._lang or self._sc or self._info.raw then
local langcode, sccode, lang, sc = self._data.catfix, self._data.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
elseif langcode == nil then -- not false
lang = self._lang
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
elseif sccode == nil then -- not false
sc = self._sc
end
return lang, sc
elseif not self._data.umbrella then
return
end
-- umbrella
local langcode, sccode, lang, sc = self._data.umbrella.catfix, self._data.umbrella.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
end
return lang, sc
end
function Category:getTOCTemplateName()
-- This should only be invoked if getTOC() returns true, meaning to do the default algorithm, but getTOC()
-- implements its own default algorithm.
internal_error("This should never get called")
end
local export = {}
function export.main(info)
local self = setmetatable({_info = info}, Category)
self:initCommon()
return self._data and self or nil
end
export.new = Category.new
return export
o45t2ki3sumefh0zo037mj8zxk50lem
36941
36933
2026-08-18T01:27:13Z
Ghybu
12
پووچەڵکردنەوەی پێداچوونەوەی [[Special:Diff/36933|36933]] لە لایەن [[Special:Contributions/Ghybu|Ghybu]] ([[User talk:Ghybu|لێدوان]])
36941
Scribunto
text/plain
local lang_independent_data = require("Module:category tree/data")
local lang_specific_module = "Module:category tree/lang"
local lang_specific_module_prefix = lang_specific_module .. "/"
local family_specific_module = "Module:category tree/fam"
local family_specific_module_prefix = family_specific_module .. "/"
local labels_utilities_module = "Module:labels/utilities"
local template_parser_module = "Module:template parser"
local concat = table.concat
local dump = mw.dumpObject
local expand_template = require("Module:frame").expandTemplate
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local lcfirst = require("Module:string utilities").lcfirst
local list_to_set = require("Module:table").listToSet
local make_title = mw.title.makeTitle
local new_title = mw.title.new
local parse = require(template_parser_module).parse
local sparse_concat = require("Module:table").sparseConcat
local tostring = tostring
local type = type
local ucfirst = require("Module:string utilities").ucfirst
local uupper = require("Module:string utilities").upper
local function internal_error(msg)
error("Internal error: " .. msg)
end
local function get_lang(...)
local _get_lang = require("Module:languages").getByCode
function get_lang(...)
return _get_lang(...) or require("Module:languages/errorGetBy").code(...)
end
return get_lang(...)
end
local function get_script(...)
local _get_script = require("Module:scripts").getByCode
function get_script(code)
return _get_script(code) or require("Module:languages/error")(code, true, "script code")
end
return get_script(...)
end
-- Category object
local Category = {}
Category.__index = Category
function Category:get_originating_info()
local originating_info = ""
if self._info.originating_label then
originating_info = " (originating from label \"" .. self._info.originating_label .. "\" in module [[" .. self._info.originating_module .. "]])"
end
return originating_info
end
local valid_keys = list_to_set{"code", "label", "sc", "raw", "args", "also", "called_from_inside", "originating_label", "originating_module"}
function Category.new(info)
for key in pairs(info) do
if not valid_keys[key] then
internal_error("The parameter \"" .. key .. "\" was not recognized.")
end
end
local self = setmetatable({}, Category)
self._info = info
if not self._info.label then
internal_error("No label was specified.")
end
self:initCommon()
if not self._data then
internal_error("The " .. (self._info.raw and "raw " or "") .. "label \"" .. self._info.label .. "\" does not exist" .. self:get_originating_info() .. ".")
end
return self
end
function Category:initCommon()
local function patch_args(args)
-- This fixes the issue with Scribunto automatically converting keys
-- in a table as numbers to strings, which in turn causes a circular
-- error for having argument parameter names as numbers as strings.
if type(args) ~= "table" then
return args
end
local new_args = {}
for k, v in pairs(args) do
if type(k) == "string" and string.len(k) < 10 and not string.match(k, "^0") and string.match(k, "^%d+$") then
new_args[tonumber(k)] = patch_args(v)
else
new_args[k] = patch_args(v)
end
end
return new_args
end
local args_handled = false
if self._info.raw then
-- Check if the category exists
local raw_categories = lang_independent_data["RAW_CATEGORIES"]
self._data = raw_categories[self._info.label]
if self._data then
if self._data.lang then
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
else
-- Go through raw handlers
local data = {
category = self._info.label,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["RAW_HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
if self._data then
-- Update the label if the handler specified a canonical name for it.
if self._data.canonical_name then
self._info.canonical_name = self._data.canonical_name
end
if self._data.lang then
if type(self._data.lang) ~= "string" then
internal_error("Received non-string value " .. dump(self._data.lang) .. " for self._data.lang, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
if type(self._data.sc) ~= "string" then
internal_error("Received non-string value " .. dump(self._data.sc) .. " for self._data.sc, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
end
end
else
-- Already parsed into language + label
if self._info.code then
self._lang = get_lang(self._info.code)
else
self._lang = nil
end
if self._info.sc then
self._sc = get_script(self._info.sc)
else
self._sc = nil
end
self._info.orig_label = self._info.label
if not self._lang then
-- Umbrella categories without a preceding language always begin with a capital letter, but the actual label may be
-- lowercase (cf. [[:Category:Nouns by language]] with label 'nouns' with per-language [[:Category:English nouns]];
-- but [[:Category:Reddit slang by language]] with label 'Reddit slang' with per-language
-- [[:Category:English Reddit slang]]). Since the label is almost always lowercase, we lowercase it for umbrella
-- categories, storing the original into `orig_label`, and correct it later if needed.
self._info.label = lcfirst(self._info.label)
end
-- First, check lang-specific labels and handlers if this is not an umbrella category.
if self._lang then
local objects_with_modules = require(lang_specific_module)
local obj, seen = self._lang, {}
local object_specific_module_prefix = lang_specific_module_prefix
local is_family = false
repeat
if objects_with_modules[obj:getCode()] then
local module = object_specific_module_prefix .. obj:getCode()
local labels_and_handlers = require(module)
if labels_and_handlers.LABELS then
self._data = labels_and_handlers.LABELS[self._info.label]
if self._data then
if not is_family and self._data.umbrella == nil and self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
end
end
if not self._data and labels_and_handlers.HANDLERS then
for _, handler in ipairs(labels_and_handlers.HANDLERS) do
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
self._data, args_handled = handler(data)
if self._data then
if not is_family and self._data.umbrella == nil and
self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
break
end
end
end
if self._data then
break
end
end
seen[obj:getCode()] = true
obj = obj:getFamily()
if not is_family then
is_family = true
object_specific_module_prefix = family_specific_module_prefix
objects_with_modules = require(family_specific_module)
end
until not obj or seen[obj:getCode()]
end
local function fetch_label_data(labels)
self._data = labels[self._info.label]
-- See comment above about uppercase- vs. lowercase-initial labels, which are indistinguishable
-- in umbrella categories.
if not self._data then
self._data = labels[self._info.orig_label]
if self._data then
self._info.label = self._info.orig_label
end
end
end
-- Then check lang-independent labels.
if not self._data then
-- lang_independent_data.LABELS should always exist.
fetch_label_data(lang_independent_data.LABELS)
if not self._data and not self._lang then
-- Check family-specific labels for umbrella label.
local families_with_modules = require(family_specific_module)
for famcode, _ in pairs(families_with_modules) do
local module = family_specific_module_prefix .. famcode
local labels_and_handlers = require(module)
if labels_and_handlers.LABELS then
fetch_label_data(labels_and_handlers.LABELS)
if self._data then
self._data.module = self._data.module or module
break
end
end
end
end
end
-- Then check lang-independent handlers.
if not self._data then
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
if not self._data and not self._lang then
-- Check family-specific labels for umbrella handler.
local families_with_modules = require(family_specific_module)
for famcode, _ in pairs(families_with_modules) do
local module = family_specific_module_prefix .. famcode
local labels_and_handlers = require(module)
if labels_and_handlers.HANDLERS then
for _, handler in ipairs(labels_and_handlers.HANDLERS) do
local data = {
label = self._info.label,
sc = self._sc,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
self._data, args_handled = handler(data)
if self._data then
self._data.module = self._data.module or module
break
end
end
end
if self._data then
break
end
end
end
end
end
if not args_handled and self._data and self._info.args and next(self._info.args) then
local module_text = " (handled in [[" .. (self._data.module or "UNKNOWN").. "]])"
local args_text = {}
for k, v in pairs(self._info.args) do
insert(args_text, k .. "=" .. ((type(v) == "string" or type(v) == "number") and v or dump(v)))
end
error("poscatboiler label '" .. self._info.label .. "' " .. module_text .. " doesn't accept extra args " ..
concat(args_text, ", "))
end
if self._sc and not self._lang then
internal_error("Umbrella categories cannot have a script specified.")
end
end
function Category:convert_spec_to_string(desc)
if not desc then
return desc
end
local desc_type = type(desc)
if desc_type == "string" then
return desc
elseif desc_type == "number" then
return tostring(desc)
elseif not is_callable(desc) then
internal_error("`desc` must be a string, number, function, callable table or nil; received " .. dump(desc))
end
desc = desc {
lang = self._lang,
sc = self._sc,
label = self._info.label,
raw = self._info.raw,
}
if not desc then
return desc
end
desc_type = type(desc)
if desc_type == "string" then
return desc
end
internal_error("The value returned by `desc` must be a string or nil; received " .. dump(desc))
end
local function add_obj_args(args, obj, obj_type)
if obj then
args[obj_type .. "code"] = obj:getCode()
args[obj_type .. "name"] = obj:getCanonicalName()
args[obj_type .. "disp"] = obj:getDisplayForm()
args[obj_type .. "cat"] = obj:getCategoryName()
args[obj_type .. "link"] = obj:makeCategoryLink()
end
end
-- Expands `desc` like a template, passing values for specs like {{{langname}}}.
function Category:substitute_template_specs(desc)
-- This may end up happening twice but that's OK as the function is (usually) idempotent.
-- FIXME: Not idempotent if a preprocessed template returns wikicode.
desc = self:convert_spec_to_string(desc)
if not desc then
return nil
end
-- Populate the substitution arguments.
local args = {}
args.umbrella_msg = "ئەمە پۆلێکی گشتگیرە. ھیچ سەروشەیەکی فەرھەنگی تێدا نییە، بەڵکوو تەنیا پۆلەکانی تری تایبەت بە زمانی تێدایە، کە ئەوانیش چەمکە پەیوەندیدارەکان بەو زمانەیان تێدایە."
args.umbrella_meta_msg = "This is an umbrella metacategory, covering a general area such as \"lemmas\", \"names\" or \"terms by etymology\". It contains no dictionary entries, but holds only umbrella (\"by language\") categories covering specific subtopics, which in turn contain language-specific categories holding terms in a given language for that same topic."
add_obj_args(args, self._lang, "lang")
add_obj_args(args, self._sc, "sc")
return parse(desc, true):expand(args)
end
function Category:substitute_template_specs_in_args(args)
if not args then
return args
end
local pinfo = {}
for k, v in pairs(args) do
pinfo[self:substitute_template_specs(k)] = self:substitute_template_specs(v)
end
return pinfo
end
function Category:make_new(info)
info.originating_label = self._info.label
info.originating_module = self._data.module
info.called_from_inside = true
return Category.new(info)
end
function Category:getBreadcrumbName()
local ret
if self._lang or self._info.raw then
ret = self._data.breadcrumb or self._data.breadcrumb_and_first_sort_base
else
ret = self._data.umbrella and (self._data.umbrella.breadcrumb or self._data.umbrella.breadcrumb_and_first_sort_base)
end
if not ret then
ret = self._info.label
end
if type(ret) ~= "table" then
ret = {name = ret}
end
local name = self:substitute_template_specs(ret.name)
local nocap = ret.nocap
if self._sc then
name = name .. " in " .. self._sc:getDisplayForm()
end
return name, nocap
end
local function expand_toc_template_if(template)
local template_obj = new_title(template, 10)
if template_obj.exists then
return expand_template{title = template_obj.text}
end
return nil
end
-- Return the textual expansion of the first existing template among the given templates, first performing
-- substitutions on the template name such as replacing {{{langcode}}} with the current language's code (if any).
-- If no templates exist after expansion, or if nil is passed in, return nil. If a single string is passed in,
-- treat it like a one-element list consisting of that string.
function Category:get_template_text(templates)
if templates == nil then
return nil
elseif type(templates) ~= "table" then
templates = {templates}
end
for _, template in ipairs(templates) do
if template == false then
return false
end
template = self:substitute_template_specs(template)
return expand_toc_template_if(template)
end
return nil
end
function Category:getTOC(toc_type)
-- Type "none" means everything fits on a single page; in that case, display nothing.
if toc_type == "none" then
return nil
end
local templates, fallback_templates
-- If TOC type is "full" (more than 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template_full` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. look up and expand the `toc_template` templates (normal or umbrella, as above);
-- 3. do the default behavior, which is as follows:
-- 3a. look up a language-specific "full" template according to the current language (using English if there
-- is no current language);
-- 3b. look up a script-specific "full" template according to the first script of current language (using English
-- if there is no current language);
-- 3c. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 3d. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 3e. display nothing.
--
-- If TOC type is "normal" (between 200 and 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. do the default behavior, which is as follows:
-- 2a. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 2b. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 2c. display nothing.
local data_source
if self._lang or self._info.raw then
data_source = self._data
else
data_source = self._data.umbrella
end
if data_source then
if toc_type == "full" then
templates = data_source.toc_template_full
fallback_templates = data_source.toc_template
else
templates = data_source.toc_template
end
end
local text = self:get_template_text(templates)
if text then
return text
elseif text == false then
return nil
end
text = self:get_template_text(fallback_templates)
if text then
return text
elseif text == false then
return nil
end
local default_toc_templates_to_check = {}
local lang, sc = self:getCatfixInfo()
local langcode = lang and lang:getCode() or "en"
local sccode = sc and sc:getCode() or lang and lang:getScriptCodes()[1] or "Latn"
-- FIXME: What is toctemplateprefix used for?
local tocname = (self._data.toctemplateprefix or "") .. "categoryTOC"
if toc_type == "full" then
insert(default_toc_templates_to_check, ("%s-%s/full"):format(langcode, tocname))
insert(default_toc_templates_to_check, ("%s-%s/full"):format(sccode, tocname))
end
insert(default_toc_templates_to_check, ("%s-%s"):format(langcode, tocname))
insert(default_toc_templates_to_check, ("%s-%s"):format(sccode, tocname))
for _, toc_template in ipairs(default_toc_templates_to_check) do
local toc_template_text = expand_toc_template_if(toc_template)
if toc_template_text then
return toc_template_text
end
end
return nil
end
function Category:getInfo()
return self._info
end
function Category:getDataModule()
return self._data.module
end
function Category:canBeEmpty()
if self._lang or self._info.raw then
return self._data.can_be_empty
end
return self._data.umbrella and self._data.umbrella.can_be_empty
end
function Category:isHidden()
if self._lang or self._info.raw then
return self._data.hidden
end
return self._data.umbrella and self._data.umbrella.hidden
end
function Category:getCategoryName()
if self._info.raw then
return self._info.canonical_name or self._info.label
elseif self._lang then
local ret = self._info.label .. " بە " .. self._lang:getCanonicalName()
if self._sc then
ret = ret .. " in " .. self._sc:getDisplayForm()
end
return ucfirst(ret)
end
local ret = ucfirst(self._info.label)
if not (self._data.no_by_language or self._data.umbrella and self._data.umbrella.no_by_language) then
ret = ret .. " by language"
end
return ret
end
function Category:getTopright()
if self._lang or self._info.raw then
return self:substitute_template_specs(self._data.topright)
end
return self._data.umbrella and self:substitute_template_specs(self._data.umbrella.topright)
end
function Category:display_title(displaytitle, lang)
if type(displaytitle) == "string" then
displaytitle = self:substitute_template_specs(displaytitle)
else
displaytitle = displaytitle(self:getCategoryName(), lang)
end
mw.getCurrentFrame():callParserFunction("DISPLAYTITLE", "Category:" .. displaytitle)
end
function Category:get_labels_categorizing()
local m_labels_utilities = require(labels_utilities_module)
local pos_cat_labels, sense_cat_labels, use_tlb
pos_cat_labels = m_labels_utilities.find_labels_for_category(self._info.label, "pos", self._lang)
local sense_label = self._info.label:match("^(.*) terms$")
if sense_label then
use_tlb = true
else
sense_label = self._info.label:match("^terms with (.*) senses$")
end
if not sense_label then
return nil
end
sense_cat_labels = m_labels_utilities.find_labels_for_category(sense_label, "sense", self._lang)
if use_tlb then
return m_labels_utilities.format_labels_categorizing(pos_cat_labels, sense_cat_labels, self._lang)
end
local all_labels = pos_cat_labels
for k, v in pairs(sense_cat_labels) do
all_labels[k] = v
end
return m_labels_utilities.format_labels_categorizing(all_labels, nil, self._lang)
end
-- FIXME: this is clunky.
local function remove_lang_params(desc)
-- Simply remove a language name/code/category from the beginning of the string, but replace the language name
-- in the middle of the string with either "specific languages" or "specific-language" depending on whether the
-- language name appears to be an attributive qualifier of another noun or to stand by itself. This may be wrong,
-- in which case the category in question should supply its own umbrella description.
desc = desc:gsub("^{{{langname}}} ", "")
:gsub("{{{langname}}} %(", "specific languages (")
:gsub("{{{langname}}}([.,])", "specific languages%1")
:gsub("{{{langname}}} ", "specific-language ")
:gsub("{{{langdisp}}}", "specific languages")
:gsub("{{{langlink}}}", "specific languages")
return desc
end
function Category:getDescription(isChild)
-- Allows different text in the list of a category's children
local isChild = isChild == "child"
if self._lang or self._info.raw then
if not isChild and self._data.displaytitle then
self:display_title(self._data.displaytitle, self._lang)
end
if self._sc then
return self:getCategoryName() .. "."
end
local desc = self:substitute_template_specs(self._data.description)
if not desc then
return nil
elseif isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(self._data.preceding),
desc,
self:substitute_template_specs(self._data.additional),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
local umbrella = self._data.umbrella
if not isChild and umbrella and umbrella.displaytitle then
self:display_title(umbrella.displaytitle)
end
local desc = self:substitute_template_specs(umbrella and umbrella.description)
local has_umbrella_desc = not not desc
if not desc then
desc = self:convert_spec_to_string(self._data.description)
if desc then
desc = remove_lang_params(desc)
desc = lcfirst(desc)
desc = desc:gsub("%.$", "")
desc = "Categories with " .. desc .. "."
else
desc = "Categories with " .. self._info.label .. " in various specific languages."
end
desc = self:substitute_template_specs(desc)
end
if isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(umbrella and umbrella.preceding or not has_umbrella_desc and self._data.preceding),
desc,
self:substitute_template_specs(umbrella and umbrella.additional or not has_umbrella_desc and self._data.additional),
self:substitute_template_specs("{{{umbrella_msg}}}"),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
function Category:new_sortkey(sortkey)
local sortkey_type = type(sortkey)
if sortkey_type == "string" then
sortkey = uupper(sortkey)
elseif sortkey_type == "table" then
function sortkey:makeSortKey()
local sort_func = self.sort_func
if sort_func ~= nil then
return sort_func(self.sort_base)
end
local lang = self.lang
if lang == nil then
return self.sort_base
end
lang = get_lang(lang, nil, true)
if lang == nil then
return self.sort_base
end
local sc = self.sc
if sc ~= nil then
sc = get_script(sc)
end
return lang:makeSortKey(self.sort_base, sc)
end
end
return sortkey
end
function Category:inherit_spec(spec, parent_spec, substitute_result)
if spec == false then
return nil
end
local retval = spec or parent_spec
if substitute_result then
retval = self:substitute_template_specs(retval)
end
return retval
end
function Category:canonicalize_parents_children(cats, is_children, fallback_sort_base)
if not cats then
return nil
elseif type(cats) == "table" then
if cats.name or cats.module then
cats = {cats}
elseif #cats == 0 then
return nil
end
else
cats = {cats}
end
local ret = {}
for _, cat in ipairs(cats) do
if type(cat) ~= "table" or not cat.name and not cat.module then
cat = {name = cat}
end
insert(ret, cat)
end
local is_umbrella = not self._lang and not self._info.raw
local table_type = is_children and "extra_children" or "parents"
for i, cat in ipairs(ret) do
local raw
if self._info.raw or is_umbrella then
raw = not cat.is_label
else
raw = cat.raw
end
local lang = self:inherit_spec(cat.lang, not raw and self._info.code or nil, "substitute")
local sc = self:inherit_spec(cat.sc, not raw and self._info.sc or nil, "substitute")
-- Get the sortkey.
local sortkey = self:inherit_spec(cat.sort, i == 1 and fallback_sort_base and {sort_base = fallback_sort_base} or nil)
if type(sortkey) == "table" then
sortkey.sort_base = self:substitute_template_specs(sortkey.sort_base) or
internal_error("Missing .sort_base in '" .. table_type .. "' .sort table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
if sortkey.sort_func then
-- Not allowed to give a lang and/or script if sort_func is given.
local bad_spec = sortkey.lang and "lang" or sortkey.sc and "sc" or nil
if bad_spec then
internal_error("Cannot specify both ." .. bad_spec .. " and .sort_func in '" .. table_type ..
"' .sort table for '" .. self._info.label .. "' category entry in module '" ..
(self._data.module or "unknown") .. "'")
end
else
sortkey.lang = self:inherit_spec(sortkey.lang, lang, "substitute")
sortkey.sc = self:inherit_spec(sortkey.sc, sc, "substitute")
end
else
sortkey = self:substitute_template_specs(sortkey)
end
local name
if cat.module then
-- A reference to a category using another category tree module.
if not cat.args then
internal_error("Missing .args in '" .. table_type .. "' table with module=\"" .. cat.module .. "\" for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
end
name = require("Module:category tree/" .. cat.module).new(self:substitute_template_specs_in_args(cat.args))
else
name = cat.name
if not name then
internal_error("Missing .name in " .. (is_umbrella and "umbrella " or "") .. "'" .. table_type .. "' table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
elseif type(name) == "string" then -- otherwise, assume it's a category object and use it directly
name = self:substitute_template_specs(name)
if name:find("^Category:") then
-- It's a non-poscatboiler category name.
sortkey = sortkey or is_children and name:gsub("^Category:", "") or self:getCategoryName()
else
-- It's a label.
sortkey = sortkey or is_children and name or self._info.label
name = self:make_new{
label = name, code = lang, sc = sc,
raw = raw, args = self:substitute_template_specs_in_args(cat.args)
}
end
end
end
sortkey = sortkey or is_children and " " or self._info.label
ret[i] = {
name = name,
description = is_children and self:substitute_template_specs(cat.description) or nil,
sort = self:new_sortkey(sortkey)
}
end
return ret
end
function Category:getParents()
local is_umbrella, ret = not self._lang and not self._info.raw
if self._sc then
local parent1 = self:make_new{code = self._info.code, label = "terms in " .. self._sc:getCanonicalName() .. " script"}
local parent2 = self:make_new{code = self._info.code, label = self._info.label, raw = self._info.raw, args = self._info.args}
ret = {
{name = parent1, sort = self._sc:getCanonicalName()},
{name = parent2, sort = self._sc:getCanonicalName()},
}
else
local parents, fallback_sort_base
if is_umbrella then
parents = self._data.umbrella and self._data.umbrella.parents or self._data.umbrella_parents
fallback_sort_base = self._data.umbrella and self._data.umbrella.breadcrumb_and_first_sort_base or nil
else
parents = self._data.parents
fallback_sort_base = self._data.breadcrumb_and_first_sort_base
end
ret = self:canonicalize_parents_children(parents, nil, fallback_sort_base)
if not ret then
return nil
end
end
local self_cat = self:getCategoryName()
for _, parent in ipairs(ret) do
local parent_cat = parent.name.getCategoryName and parent.name:getCategoryName()
if self_cat == parent_cat then
internal_error(("Infinite loop would occur, as parent category '%s' is the same as the child category"):format(self_cat))
end
end
return ret
end
function Category:getChildren()
local is_umbrella = not self._lang and not self._info.raw
local children = self._data.children
local ret = {}
if not is_umbrella and children then
for _, child in ipairs(children) do
child = mw.clone(child)
if type(child) ~= "table" then
child = {name = child}
end
if not child.sort then
child.sort = child.name
end
-- FIXME, is preserving the script correct?
child.name = self:make_new{code = self._info.code, label = child.name, raw = child.raw, sc = self._info.sc}
insert(ret, child)
end
end
local extra_children
if is_umbrella then
extra_children = self._data.umbrella and self._data.umbrella.extra_children
else
extra_children = self._data.extra_children
end
extra_children = self:canonicalize_parents_children(extra_children, "children")
if extra_children then
for _, child in ipairs(extra_children) do
insert(ret, child)
end
end
return #ret > 0 and ret or nil
end
function Category:getUmbrella()
local umbrella = self._data.umbrella
if umbrella == false or self._info.raw or not self._lang or self._sc then
return nil
end
-- If `umbrella` is a string, use that; otherwise, use the label.
return self:make_new({label = type(umbrella) == "string" and umbrella or self._info.label})
end
function Category:getAppendix()
-- FIXME, this should be customizable.
local lang, label = self._lang, self._info.label
if self._info.raw or not (lang and label) then
return nil
end
local appendix = make_title(100, lang:getCanonicalName() .. " " .. label)
return appendix.exists and appendix.fullText or nil
end
function Category:getCatfixInfo()
if self._lang or self._sc or self._info.raw then
local langcode, sccode, lang, sc = self._data.catfix, self._data.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
elseif langcode == nil then -- not false
lang = self._lang
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
elseif sccode == nil then -- not false
sc = self._sc
end
return lang, sc
elseif not self._data.umbrella then
return
end
-- umbrella
local langcode, sccode, lang, sc = self._data.umbrella.catfix, self._data.umbrella.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
end
return lang, sc
end
function Category:getTOCTemplateName()
-- This should only be invoked if getTOC() returns true, meaning to do the default algorithm, but getTOC()
-- implements its own default algorithm.
internal_error("This should never get called")
end
local export = {}
function export.main(info)
local self = setmetatable({_info = info}, Category)
self:initCommon()
return self._data and self or nil
end
export.new = Category.new
return export
2en0fruvknv7e2aj4r2968jkh2854zh
36942
36941
2026-08-18T01:28:40Z
Ghybu
12
پووچەڵکردنەوەی پێداچوونەوەی [[Special:Diff/36941|36941]] لە لایەن [[Special:Contributions/Ghybu|Ghybu]] ([[User talk:Ghybu|لێدوان]])
36942
Scribunto
text/plain
local lang_independent_data = require("Module:category tree/data")
local lang_specific_module = "Module:category tree/lang"
local lang_specific_module_prefix = lang_specific_module .. "/"
local family_specific_module = "Module:category tree/fam"
local family_specific_module_prefix = family_specific_module .. "/"
local labels_utilities_module = "Module:labels/utilities"
local template_parser_module = "Module:template parser"
local concat = table.concat
local dump = mw.dumpObject
local expand_template = require("Module:frame").expandTemplate
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local lcfirst = require("Module:string utilities").lcfirst
local list_to_set = require("Module:table").listToSet
local make_title = mw.title.makeTitle
local new_title = mw.title.new
local parse = require(template_parser_module).parse
local sparse_concat = require("Module:table").sparseConcat
local tostring = tostring
local type = type
local ucfirst = require("Module:string utilities").ucfirst
local uupper = require("Module:string utilities").upper
local function internal_error(msg)
error("Internal error: " .. msg)
end
local function get_lang(...)
local _get_lang = require("Module:languages").getByCode
function get_lang(...)
return _get_lang(...) or require("Module:languages/errorGetBy").code(...)
end
return get_lang(...)
end
local function get_script(...)
local _get_script = require("Module:scripts").getByCode
function get_script(code)
return _get_script(code) or require("Module:languages/error")(code, true, "script code")
end
return get_script(...)
end
-- Category object
local Category = {}
Category.__index = Category
function Category:get_originating_info()
local originating_info = ""
if self._info.originating_label then
originating_info = " (originating from label \"" .. self._info.originating_label .. "\" in module [[" .. self._info.originating_module .. "]])"
end
return originating_info
end
local valid_keys = list_to_set{"code", "label", "sc", "raw", "args", "also", "called_from_inside", "originating_label", "originating_module"}
function Category.new(info)
for key in pairs(info) do
if not valid_keys[key] then
internal_error("The parameter \"" .. key .. "\" was not recognized.")
end
end
local self = setmetatable({}, Category)
self._info = info
if not self._info.label then
internal_error("No label was specified.")
end
self:initCommon()
if not self._data then
internal_error("The " .. (self._info.raw and "raw " or "") .. "label \"" .. self._info.label .. "\" does not exist" .. self:get_originating_info() .. ".")
end
return self
end
function Category:initCommon()
local function patch_args(args)
-- This fixes the issue with Scribunto automatically converting keys
-- in a table as numbers to strings, which in turn causes a circular
-- error for having argument parameter names as numbers as strings.
if type(args) ~= "table" then
return args
end
local new_args = {}
for k, v in pairs(args) do
if type(k) == "string" and string.len(k) < 10 and not string.match(k, "^0") and string.match(k, "^%d+$") then
new_args[tonumber(k)] = patch_args(v)
else
new_args[k] = patch_args(v)
end
end
return new_args
end
local args_handled = false
if self._info.raw then
-- Check if the category exists
local raw_categories = lang_independent_data["RAW_CATEGORIES"]
self._data = raw_categories[self._info.label]
if self._data then
if self._data.lang then
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
else
-- Go through raw handlers
local data = {
category = self._info.label,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["RAW_HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
if self._data then
-- Update the label if the handler specified a canonical name for it.
if self._data.canonical_name then
self._info.canonical_name = self._data.canonical_name
end
if self._data.lang then
if type(self._data.lang) ~= "string" then
internal_error("Received non-string value " .. dump(self._data.lang) .. " for self._data.lang, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
if type(self._data.sc) ~= "string" then
internal_error("Received non-string value " .. dump(self._data.sc) .. " for self._data.sc, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
end
end
else
-- Already parsed into language + label
if self._info.code then
self._lang = get_lang(self._info.code)
else
self._lang = nil
end
if self._info.sc then
self._sc = get_script(self._info.sc)
else
self._sc = nil
end
self._info.orig_label = self._info.label
if not self._lang then
-- Umbrella categories without a preceding language always begin with a capital letter, but the actual label may be
-- lowercase (cf. [[:Category:Nouns by language]] with label 'nouns' with per-language [[:Category:English nouns]];
-- but [[:Category:Reddit slang by language]] with label 'Reddit slang' with per-language
-- [[:Category:English Reddit slang]]). Since the label is almost always lowercase, we lowercase it for umbrella
-- categories, storing the original into `orig_label`, and correct it later if needed.
self._info.label = lcfirst(self._info.label)
end
-- First, check lang-specific labels and handlers if this is not an umbrella category.
if self._lang then
local objects_with_modules = require(lang_specific_module)
local obj, seen = self._lang, {}
local object_specific_module_prefix = lang_specific_module_prefix
local is_family = false
repeat
if objects_with_modules[obj:getCode()] then
local module = object_specific_module_prefix .. obj:getCode()
local labels_and_handlers = require(module)
if labels_and_handlers.LABELS then
self._data = labels_and_handlers.LABELS[self._info.label]
if self._data then
if not is_family and self._data.umbrella == nil and self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
end
end
if not self._data and labels_and_handlers.HANDLERS then
for _, handler in ipairs(labels_and_handlers.HANDLERS) do
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
self._data, args_handled = handler(data)
if self._data then
if not is_family and self._data.umbrella == nil and
self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
break
end
end
end
if self._data then
break
end
end
seen[obj:getCode()] = true
obj = obj:getFamily()
if not is_family then
is_family = true
object_specific_module_prefix = family_specific_module_prefix
objects_with_modules = require(family_specific_module)
end
until not obj or seen[obj:getCode()]
end
local function fetch_label_data(labels)
self._data = labels[self._info.label]
-- See comment above about uppercase- vs. lowercase-initial labels, which are indistinguishable
-- in umbrella categories.
if not self._data then
self._data = labels[self._info.orig_label]
if self._data then
self._info.label = self._info.orig_label
end
end
end
-- Then check lang-independent labels.
if not self._data then
-- lang_independent_data.LABELS should always exist.
fetch_label_data(lang_independent_data.LABELS)
if not self._data and not self._lang then
-- Check family-specific labels for umbrella label.
local families_with_modules = require(family_specific_module)
for famcode, _ in pairs(families_with_modules) do
local module = family_specific_module_prefix .. famcode
local labels_and_handlers = require(module)
if labels_and_handlers.LABELS then
fetch_label_data(labels_and_handlers.LABELS)
if self._data then
self._data.module = self._data.module or module
break
end
end
end
end
end
-- Then check lang-independent handlers.
if not self._data then
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
if not self._data and not self._lang then
-- Check family-specific labels for umbrella handler.
local families_with_modules = require(family_specific_module)
for famcode, _ in pairs(families_with_modules) do
local module = family_specific_module_prefix .. famcode
local labels_and_handlers = require(module)
if labels_and_handlers.HANDLERS then
for _, handler in ipairs(labels_and_handlers.HANDLERS) do
local data = {
label = self._info.label,
sc = self._sc,
args = patch_args(self._info.args) or {},
called_from_inside = self._info.called_from_inside,
}
self._data, args_handled = handler(data)
if self._data then
self._data.module = self._data.module or module
break
end
end
end
if self._data then
break
end
end
end
end
end
if not args_handled and self._data and self._info.args and next(self._info.args) then
local module_text = " (handled in [[" .. (self._data.module or "UNKNOWN").. "]])"
local args_text = {}
for k, v in pairs(self._info.args) do
insert(args_text, k .. "=" .. ((type(v) == "string" or type(v) == "number") and v or dump(v)))
end
error("poscatboiler label '" .. self._info.label .. "' " .. module_text .. " doesn't accept extra args " ..
concat(args_text, ", "))
end
if self._sc and not self._lang then
internal_error("Umbrella categories cannot have a script specified.")
end
end
function Category:convert_spec_to_string(desc)
if not desc then
return desc
end
local desc_type = type(desc)
if desc_type == "string" then
return desc
elseif desc_type == "number" then
return tostring(desc)
elseif not is_callable(desc) then
internal_error("`desc` must be a string, number, function, callable table or nil; received " .. dump(desc))
end
desc = desc {
lang = self._lang,
sc = self._sc,
label = self._info.label,
raw = self._info.raw,
}
if not desc then
return desc
end
desc_type = type(desc)
if desc_type == "string" then
return desc
end
internal_error("The value returned by `desc` must be a string or nil; received " .. dump(desc))
end
local function add_obj_args(args, obj, obj_type)
if obj then
args[obj_type .. "code"] = obj:getCode()
args[obj_type .. "name"] = obj:getCanonicalName()
args[obj_type .. "disp"] = obj:getDisplayForm()
args[obj_type .. "cat"] = obj:getCategoryName()
args[obj_type .. "link"] = obj:makeCategoryLink()
end
end
-- Expands `desc` like a template, passing values for specs like {{{langname}}}.
function Category:substitute_template_specs(desc)
-- This may end up happening twice but that's OK as the function is (usually) idempotent.
-- FIXME: Not idempotent if a preprocessed template returns wikicode.
desc = self:convert_spec_to_string(desc)
if not desc then
return nil
end
-- Populate the substitution arguments.
local args = {}
args.umbrella_msg = "ئەمە پۆلێکی گشتگیرە. ھیچ سەروشەیەکی فەرھەنگی تێدا نییە، بەڵکوو تەنیا پۆلەکانی تری تایبەت بە زمانی تێدایە، کە ئەوانیش چەمکە پەیوەندیدارەکان بەو زمانەیان تێدایە."
args.umbrella_meta_msg = "This is an umbrella metacategory, covering a general area such as \"lemmas\", \"names\" or \"terms by etymology\". It contains no dictionary entries, but holds only umbrella (\"by language\") categories covering specific subtopics, which in turn contain language-specific categories holding terms in a given language for that same topic."
add_obj_args(args, self._lang, "lang")
add_obj_args(args, self._sc, "sc")
return parse(desc, true):expand(args)
end
function Category:substitute_template_specs_in_args(args)
if not args then
return args
end
local pinfo = {}
for k, v in pairs(args) do
pinfo[self:substitute_template_specs(k)] = self:substitute_template_specs(v)
end
return pinfo
end
function Category:make_new(info)
info.originating_label = self._info.label
info.originating_module = self._data.module
info.called_from_inside = true
return Category.new(info)
end
function Category:getBreadcrumbName()
local ret
if self._lang or self._info.raw then
ret = self._data.breadcrumb or self._data.breadcrumb_and_first_sort_base
else
ret = self._data.umbrella and (self._data.umbrella.breadcrumb or self._data.umbrella.breadcrumb_and_first_sort_base)
end
if not ret then
ret = self._info.label
end
if type(ret) ~= "table" then
ret = {name = ret}
end
local name = self:substitute_template_specs(ret.name)
local nocap = ret.nocap
if self._sc then
name = name .. " in " .. self._sc:getDisplayForm()
end
return name, nocap
end
local function expand_toc_template_if(template)
local template_obj = new_title(template, 10)
if template_obj.exists then
return expand_template{title = template_obj.text}
end
return nil
end
-- Return the textual expansion of the first existing template among the given templates, first performing
-- substitutions on the template name such as replacing {{{langcode}}} with the current language's code (if any).
-- If no templates exist after expansion, or if nil is passed in, return nil. If a single string is passed in,
-- treat it like a one-element list consisting of that string.
function Category:get_template_text(templates)
if templates == nil then
return nil
elseif type(templates) ~= "table" then
templates = {templates}
end
for _, template in ipairs(templates) do
if template == false then
return false
end
template = self:substitute_template_specs(template)
return expand_toc_template_if(template)
end
return nil
end
function Category:getTOC(toc_type)
-- Type "none" means everything fits on a single page; in that case, display nothing.
if toc_type == "none" then
return nil
end
local templates, fallback_templates
-- If TOC type is "full" (more than 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template_full` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. look up and expand the `toc_template` templates (normal or umbrella, as above);
-- 3. do the default behavior, which is as follows:
-- 3a. look up a language-specific "full" template according to the current language (using English if there
-- is no current language);
-- 3b. look up a script-specific "full" template according to the first script of current language (using English
-- if there is no current language);
-- 3c. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 3d. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 3e. display nothing.
--
-- If TOC type is "normal" (between 200 and 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. do the default behavior, which is as follows:
-- 2a. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 2b. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 2c. display nothing.
local data_source
if self._lang or self._info.raw then
data_source = self._data
else
data_source = self._data.umbrella
end
if data_source then
if toc_type == "full" then
templates = data_source.toc_template_full
fallback_templates = data_source.toc_template
else
templates = data_source.toc_template
end
end
local text = self:get_template_text(templates)
if text then
return text
elseif text == false then
return nil
end
text = self:get_template_text(fallback_templates)
if text then
return text
elseif text == false then
return nil
end
local default_toc_templates_to_check = {}
local lang, sc = self:getCatfixInfo()
local langcode = lang and lang:getCode() or "en"
local sccode = sc and sc:getCode() or lang and lang:getScriptCodes()[1] or "Latn"
-- FIXME: What is toctemplateprefix used for?
local tocname = (self._data.toctemplateprefix or "") .. "categoryTOC"
if toc_type == "full" then
insert(default_toc_templates_to_check, ("%s-%s/full"):format(langcode, tocname))
insert(default_toc_templates_to_check, ("%s-%s/full"):format(sccode, tocname))
end
insert(default_toc_templates_to_check, ("%s-%s"):format(langcode, tocname))
insert(default_toc_templates_to_check, ("%s-%s"):format(sccode, tocname))
for _, toc_template in ipairs(default_toc_templates_to_check) do
local toc_template_text = expand_toc_template_if(toc_template)
if toc_template_text then
return toc_template_text
end
end
return nil
end
function Category:getInfo()
return self._info
end
function Category:getDataModule()
return self._data.module
end
function Category:canBeEmpty()
if self._lang or self._info.raw then
return self._data.can_be_empty
end
return self._data.umbrella and self._data.umbrella.can_be_empty
end
function Category:isHidden()
if self._lang or self._info.raw then
return self._data.hidden
end
return self._data.umbrella and self._data.umbrella.hidden
end
function Category:getCategoryName()
if self._info.raw then
return self._info.canonical_name or self._info.label
elseif self._lang then
local ret = self._info.label .. " بە " .. self._lang:getCanonicalName()
if self._sc then
ret = ret .. " in " .. self._sc:getDisplayForm()
end
return ucfirst(ret)
end
local ret = ucfirst(self._info.label)
if not (self._data.no_by_language or self._data.umbrella and self._data.umbrella.no_by_language) then
ret = ret .. " بەپێی زمان"
end
return ret
end
function Category:getTopright()
if self._lang or self._info.raw then
return self:substitute_template_specs(self._data.topright)
end
return self._data.umbrella and self:substitute_template_specs(self._data.umbrella.topright)
end
function Category:display_title(displaytitle, lang)
if type(displaytitle) == "string" then
displaytitle = self:substitute_template_specs(displaytitle)
else
displaytitle = displaytitle(self:getCategoryName(), lang)
end
mw.getCurrentFrame():callParserFunction("DISPLAYTITLE", "Category:" .. displaytitle)
end
function Category:get_labels_categorizing()
local m_labels_utilities = require(labels_utilities_module)
local pos_cat_labels, sense_cat_labels, use_tlb
pos_cat_labels = m_labels_utilities.find_labels_for_category(self._info.label, "pos", self._lang)
local sense_label = self._info.label:match("^(.*) terms$")
if sense_label then
use_tlb = true
else
sense_label = self._info.label:match("^terms with (.*) senses$")
end
if not sense_label then
return nil
end
sense_cat_labels = m_labels_utilities.find_labels_for_category(sense_label, "sense", self._lang)
if use_tlb then
return m_labels_utilities.format_labels_categorizing(pos_cat_labels, sense_cat_labels, self._lang)
end
local all_labels = pos_cat_labels
for k, v in pairs(sense_cat_labels) do
all_labels[k] = v
end
return m_labels_utilities.format_labels_categorizing(all_labels, nil, self._lang)
end
-- FIXME: this is clunky.
local function remove_lang_params(desc)
-- Simply remove a language name/code/category from the beginning of the string, but replace the language name
-- in the middle of the string with either "specific languages" or "specific-language" depending on whether the
-- language name appears to be an attributive qualifier of another noun or to stand by itself. This may be wrong,
-- in which case the category in question should supply its own umbrella description.
desc = desc:gsub("^{{{langname}}} ", "")
:gsub("{{{langname}}} %(", "specific languages (")
:gsub("{{{langname}}}([.,])", "specific languages%1")
:gsub("{{{langname}}} ", "specific-language ")
:gsub("{{{langdisp}}}", "specific languages")
:gsub("{{{langlink}}}", "specific languages")
return desc
end
function Category:getDescription(isChild)
-- Allows different text in the list of a category's children
local isChild = isChild == "child"
if self._lang or self._info.raw then
if not isChild and self._data.displaytitle then
self:display_title(self._data.displaytitle, self._lang)
end
if self._sc then
return self:getCategoryName() .. "."
end
local desc = self:substitute_template_specs(self._data.description)
if not desc then
return nil
elseif isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(self._data.preceding),
desc,
self:substitute_template_specs(self._data.additional),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
local umbrella = self._data.umbrella
if not isChild and umbrella and umbrella.displaytitle then
self:display_title(umbrella.displaytitle)
end
local desc = self:substitute_template_specs(umbrella and umbrella.description)
local has_umbrella_desc = not not desc
if not desc then
desc = self:convert_spec_to_string(self._data.description)
if desc then
desc = remove_lang_params(desc)
desc = lcfirst(desc)
desc = desc:gsub("%.$", "")
desc = "Categories with " .. desc .. "."
else
desc = "Categories with " .. self._info.label .. " in various specific languages."
end
desc = self:substitute_template_specs(desc)
end
if isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(umbrella and umbrella.preceding or not has_umbrella_desc and self._data.preceding),
desc,
self:substitute_template_specs(umbrella and umbrella.additional or not has_umbrella_desc and self._data.additional),
self:substitute_template_specs("{{{umbrella_msg}}}"),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
function Category:new_sortkey(sortkey)
local sortkey_type = type(sortkey)
if sortkey_type == "string" then
sortkey = uupper(sortkey)
elseif sortkey_type == "table" then
function sortkey:makeSortKey()
local sort_func = self.sort_func
if sort_func ~= nil then
return sort_func(self.sort_base)
end
local lang = self.lang
if lang == nil then
return self.sort_base
end
lang = get_lang(lang, nil, true)
if lang == nil then
return self.sort_base
end
local sc = self.sc
if sc ~= nil then
sc = get_script(sc)
end
return lang:makeSortKey(self.sort_base, sc)
end
end
return sortkey
end
function Category:inherit_spec(spec, parent_spec, substitute_result)
if spec == false then
return nil
end
local retval = spec or parent_spec
if substitute_result then
retval = self:substitute_template_specs(retval)
end
return retval
end
function Category:canonicalize_parents_children(cats, is_children, fallback_sort_base)
if not cats then
return nil
elseif type(cats) == "table" then
if cats.name or cats.module then
cats = {cats}
elseif #cats == 0 then
return nil
end
else
cats = {cats}
end
local ret = {}
for _, cat in ipairs(cats) do
if type(cat) ~= "table" or not cat.name and not cat.module then
cat = {name = cat}
end
insert(ret, cat)
end
local is_umbrella = not self._lang and not self._info.raw
local table_type = is_children and "extra_children" or "parents"
for i, cat in ipairs(ret) do
local raw
if self._info.raw or is_umbrella then
raw = not cat.is_label
else
raw = cat.raw
end
local lang = self:inherit_spec(cat.lang, not raw and self._info.code or nil, "substitute")
local sc = self:inherit_spec(cat.sc, not raw and self._info.sc or nil, "substitute")
-- Get the sortkey.
local sortkey = self:inherit_spec(cat.sort, i == 1 and fallback_sort_base and {sort_base = fallback_sort_base} or nil)
if type(sortkey) == "table" then
sortkey.sort_base = self:substitute_template_specs(sortkey.sort_base) or
internal_error("Missing .sort_base in '" .. table_type .. "' .sort table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
if sortkey.sort_func then
-- Not allowed to give a lang and/or script if sort_func is given.
local bad_spec = sortkey.lang and "lang" or sortkey.sc and "sc" or nil
if bad_spec then
internal_error("Cannot specify both ." .. bad_spec .. " and .sort_func in '" .. table_type ..
"' .sort table for '" .. self._info.label .. "' category entry in module '" ..
(self._data.module or "unknown") .. "'")
end
else
sortkey.lang = self:inherit_spec(sortkey.lang, lang, "substitute")
sortkey.sc = self:inherit_spec(sortkey.sc, sc, "substitute")
end
else
sortkey = self:substitute_template_specs(sortkey)
end
local name
if cat.module then
-- A reference to a category using another category tree module.
if not cat.args then
internal_error("Missing .args in '" .. table_type .. "' table with module=\"" .. cat.module .. "\" for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
end
name = require("Module:category tree/" .. cat.module).new(self:substitute_template_specs_in_args(cat.args))
else
name = cat.name
if not name then
internal_error("Missing .name in " .. (is_umbrella and "umbrella " or "") .. "'" .. table_type .. "' table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
elseif type(name) == "string" then -- otherwise, assume it's a category object and use it directly
name = self:substitute_template_specs(name)
if name:find("^Category:") then
-- It's a non-poscatboiler category name.
sortkey = sortkey or is_children and name:gsub("^Category:", "") or self:getCategoryName()
else
-- It's a label.
sortkey = sortkey or is_children and name or self._info.label
name = self:make_new{
label = name, code = lang, sc = sc,
raw = raw, args = self:substitute_template_specs_in_args(cat.args)
}
end
end
end
sortkey = sortkey or is_children and " " or self._info.label
ret[i] = {
name = name,
description = is_children and self:substitute_template_specs(cat.description) or nil,
sort = self:new_sortkey(sortkey)
}
end
return ret
end
function Category:getParents()
local is_umbrella, ret = not self._lang and not self._info.raw
if self._sc then
local parent1 = self:make_new{code = self._info.code, label = "terms in " .. self._sc:getCanonicalName() .. " script"}
local parent2 = self:make_new{code = self._info.code, label = self._info.label, raw = self._info.raw, args = self._info.args}
ret = {
{name = parent1, sort = self._sc:getCanonicalName()},
{name = parent2, sort = self._sc:getCanonicalName()},
}
else
local parents, fallback_sort_base
if is_umbrella then
parents = self._data.umbrella and self._data.umbrella.parents or self._data.umbrella_parents
fallback_sort_base = self._data.umbrella and self._data.umbrella.breadcrumb_and_first_sort_base or nil
else
parents = self._data.parents
fallback_sort_base = self._data.breadcrumb_and_first_sort_base
end
ret = self:canonicalize_parents_children(parents, nil, fallback_sort_base)
if not ret then
return nil
end
end
local self_cat = self:getCategoryName()
for _, parent in ipairs(ret) do
local parent_cat = parent.name.getCategoryName and parent.name:getCategoryName()
if self_cat == parent_cat then
internal_error(("Infinite loop would occur, as parent category '%s' is the same as the child category"):format(self_cat))
end
end
return ret
end
function Category:getChildren()
local is_umbrella = not self._lang and not self._info.raw
local children = self._data.children
local ret = {}
if not is_umbrella and children then
for _, child in ipairs(children) do
child = mw.clone(child)
if type(child) ~= "table" then
child = {name = child}
end
if not child.sort then
child.sort = child.name
end
-- FIXME, is preserving the script correct?
child.name = self:make_new{code = self._info.code, label = child.name, raw = child.raw, sc = self._info.sc}
insert(ret, child)
end
end
local extra_children
if is_umbrella then
extra_children = self._data.umbrella and self._data.umbrella.extra_children
else
extra_children = self._data.extra_children
end
extra_children = self:canonicalize_parents_children(extra_children, "children")
if extra_children then
for _, child in ipairs(extra_children) do
insert(ret, child)
end
end
return #ret > 0 and ret or nil
end
function Category:getUmbrella()
local umbrella = self._data.umbrella
if umbrella == false or self._info.raw or not self._lang or self._sc then
return nil
end
-- If `umbrella` is a string, use that; otherwise, use the label.
return self:make_new({label = type(umbrella) == "string" and umbrella or self._info.label})
end
function Category:getAppendix()
-- FIXME, this should be customizable.
local lang, label = self._lang, self._info.label
if self._info.raw or not (lang and label) then
return nil
end
local appendix = make_title(100, lang:getCanonicalName() .. " " .. label)
return appendix.exists and appendix.fullText or nil
end
function Category:getCatfixInfo()
if self._lang or self._sc or self._info.raw then
local langcode, sccode, lang, sc = self._data.catfix, self._data.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
elseif langcode == nil then -- not false
lang = self._lang
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
elseif sccode == nil then -- not false
sc = self._sc
end
return lang, sc
elseif not self._data.umbrella then
return
end
-- umbrella
local langcode, sccode, lang, sc = self._data.umbrella.catfix, self._data.umbrella.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
end
return lang, sc
end
function Category:getTOCTemplateName()
-- This should only be invoked if getTOC() returns true, meaning to do the default algorithm, but getTOC()
-- implements its own default algorithm.
internal_error("This should never get called")
end
local export = {}
function export.main(info)
local self = setmetatable({_info = info}, Category)
self:initCommon()
return self._data and self or nil
end
export.new = Category.new
return export
o45t2ki3sumefh0zo037mj8zxk50lem
cumhuriyet
0
1108
36949
25712
2026-08-18T03:35:32Z
Ghybu
12
36949
wikitext
text/x-wiki
== تورکی ==
=== وشەڕەتناسی ===
{{واڵا}}
===ناو ===
{{head|tr|ناو}}
# [[کۆمار]]
efr8q1s3ma1cu9yb38h8i1uo64bk2l6
خۆر
0
5025
36952
31204
2026-08-18T03:51:39Z
Ghybu
12
36952
wikitext
text/x-wiki
== کوردیی ناوەندی ==
[[پەڕگە:The Sun by the Atmospheric Imaging Assembly of NASA's Solar Dynamics Observatory - 20100819.jpg|thumb|200x200px|خۆر]]
=== وشەڕەتناسی ===
{{واڵا}}
==== ناو ====
{{ckb-noun}}
* ئەو [[ئەستێرە]]یەیە کە لە ناوەندی [[کۆمەڵەی خۆر]]دایە، و نزیکترین ئەستێرەیە لە [[زەوی]]یەوە. لە [[ئەستێرەناسی]] و ئەستێرەژمێریدا ھێمای [[☉]]ی بۆ دانراوە.
# ڕۆژێکە کە جیھان ڕووناک دەکاتەوە
ھەتاو.<ref name=":0">فەرھەنگی خاڵ</ref>
# پیتێکە بەھەر ناوێکەوە نرا دەیکا بە «اسمی فاعل»
[[نانخۆر]] ، [[گۆشتخۆر]] ، [[پیاوخۆر]].<ref name=":0" />
# ڕۆژی ئاسمان.<ref name=":1">ھەنبانە بۆرینە</ref>
# پاشگر بەواتا: ئەوی دەخوا
نانخۆر.<ref name=":1" />
# خۆر: خاک، گڵ، خۆڵ<ref name=":1" /><ref>فەرهەنگی شێخانی</ref>
==== ھاوواتاکان ====
* [[ھەتاو]]<ref name=":0" />
* [[ھۆر]]<ref name=":0" /><ref name=":1" />
* [[ڕۆژ]]
* [[ڕۆ]]<ref name=":1" />
==== وەرگێڕانەکان ====
{{وەرگێڕان-سەر|خۆر}}
* عەرەبی: {{t|ar|الشمس}}
* فارسی: {{t|fa|خورشید}}
* ئیتالی: {{t|it|Sole}}
* ئەڵمانی: {{t|de|Sonne}}
* ئیسپانی: {{t|es|Sol}}
{{trans-mid}}
* ئینگلیزی: {{t|en|Sun}}
* کورمانجی: {{t|kmr|Roj}}
* تورکی: {{t|tr|Güneş}}
* ھۆلەندی: {{t|nl|Zon}}
* فەڕەنسی: {{t|fr|Soleil}}
* سوێدی: {{t|sv|Solen}}
{{وەرگێڕان-بن}}
====سەرچاوەکان====
<references />
[[پۆل:وشە سێ پیتییە کوردییەکان]]
if9prmzxexy2h5y7biw0qy3pqzaes4t
36953
36952
2026-08-18T03:52:49Z
Ghybu
12
/* کوردیی ناوەندی */
36953
wikitext
text/x-wiki
== کوردیی ناوەندی ==
[[پەڕگە:The Sun by the Atmospheric Imaging Assembly of NASA's Solar Dynamics Observatory - 20100819.jpg|thumb|200x200px|خۆر]]
=== وشەڕەتناسی ===
{{واڵا}}
=== ناو ===
{{ckb-noun}}
* ئەو [[ئەستێرە]]یەیە کە لە ناوەندی [[کۆمەڵەی خۆر]]دایە، و نزیکترین ئەستێرەیە لە [[زەوی]]یەوە. لە [[ئەستێرەناسی]] و ئەستێرەژمێریدا ھێمای [[☉]]ی بۆ دانراوە.
# ڕۆژێکە کە جیھان ڕووناک دەکاتەوە
ھەتاو.<ref name=":0">فەرھەنگی خاڵ</ref>
# پیتێکە بەھەر ناوێکەوە نرا دەیکا بە «اسمی فاعل»
[[نانخۆر]] ، [[گۆشتخۆر]] ، [[پیاوخۆر]].<ref name=":0" />
# ڕۆژی ئاسمان.<ref name=":1">ھەنبانە بۆرینە</ref>
# پاشگر بەواتا: ئەوی دەخوا
نانخۆر.<ref name=":1" />
# خۆر: خاک، گڵ، خۆڵ<ref name=":1" /><ref>فەرهەنگی شێخانی</ref>
==== ھاوواتاکان ====
* [[ھەتاو]]<ref name=":0" />
* [[ھۆر]]<ref name=":0" /><ref name=":1" />
* [[ڕۆژ]]
* [[ڕۆ]]<ref name=":1" />
==== وەرگێڕانەکان ====
{{وەرگێڕان-سەر|خۆر}}
* عەرەبی: {{t|ar|الشمس}}
* فارسی: {{t|fa|خورشید}}
* ئیتالی: {{t|it|Sole}}
* ئەڵمانی: {{t|de|Sonne}}
* ئیسپانی: {{t|es|Sol}}
{{trans-mid}}
* ئینگلیزی: {{t|en|Sun}}
* کورمانجی: {{t|kmr|Roj}}
* تورکی: {{t|tr|Güneş}}
* ھۆلەندی: {{t|nl|Zon}}
* فەڕەنسی: {{t|fr|Soleil}}
* سوێدی: {{t|sv|Solen}}
{{وەرگێڕان-بن}}
====سەرچاوەکان====
<references />
[[پۆل:وشە سێ پیتییە کوردییەکان]]
poic2iesebdhseb7y8h4wywc2nhdggw
kirin
0
7347
36917
36669
2026-08-17T22:25:13Z
Ghybu
12
/* کرمانجی */ test
36917
wikitext
text/x-wiki
== کرمانجی ==
=== گۆکردن ===
* {{kmr-IPA}}
* {{دەنگ|kmr|LL-Q36163 (kmr)-Key Mîrza-kirin.wav}}
=== کارر ===
=== کار ===
{{kmr-verb}}
# [[کردن]]
=== ناو ===
{{kmr-noun|f}}
# [[کار]], [[کردەوە]]
23plqwve7nua3znxkmsjqa3j2uvriwg
36918
36917
2026-08-17T22:27:04Z
Ghybu
12
پووچەڵکردنەوەی پێداچوونەوەی [[Special:Diff/36917|36917]] لە لایەن [[Special:Contributions/Ghybu|Ghybu]] ([[User talk:Ghybu|لێدوان]])
36918
wikitext
text/x-wiki
== کرمانجی ==
=== گۆکردن ===
* {{kmr-IPA}}
* {{دەنگ|kmr|LL-Q36163 (kmr)-Key Mîrza-kirin.wav}}
=== کار ===
{{kmr-verb}}
# [[کردن]]
=== ناو ===
{{kmr-noun|f}}
# [[کار]], [[کردەوە]]
aq7hb2bt3dtbtrl9vu7pcxnn92062qn
لۆری
0
8257
36950
32914
2026-08-18T03:37:52Z
Ghybu
12
36950
wikitext
text/x-wiki
== کوردیی ناوەندی ==
===وشەڕەتناسی ===
{{واڵا}}
=== ناو ===
{{ckb-noun}}
# ناوی ئۆتۆمۆبیلێکی زەبەلاحە کە کاری ڕاکێشان و شتی تری پێ دەکرێت
==== وەرگێڕانەکان ====
{{وەرگێڕان-سەر|}}
{{وەرگێڕان-بن}}
je9vxbiedc6itekhgqeu6ufzi2njn0j
مۆدیوول:category tree/lemmas
828
9311
36947
36849
2026-08-18T02:23:00Z
Ghybu
12
36947
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
local diminutive_augmentative_poses = {
"adjectives",
"adverbs",
"interjections",
"nouns",
"numerals",
"prefixes",
"proper nouns",
"pronouns",
"suffixes",
"verbs"
}
labels["لێماکان"] = {
description = "{{{langname}}} [[Wiktionary:Lemmas|lemmas]], categorized by their part of speech.",
umbrella_parents = "Fundamental",
parents = {{name = "{{{langcat}}}", raw = true, sort = " "}},
}
labels["abstract verbs"] = {
description = "{{{langname}}} abstract verbs of motion whose motion is multidirectional (as opposed to unidirectional) or indirect, or whose action is repeated or in a series, instead of being a single, completed action. Abstract verbs are always imperfective in aspect, even with prefixes that are normally associated with the perfective aspect.",
additional = "See also [[abstract verb]].",
parents = {"کارەکان"},
}
labels["action nouns"] = {
description = "{{{langname}}} nouns denoting action of a verb or verbal root that it is derived from.",
parents = {"ناوەکان"},
}
labels["act-related adverbs"] = {
description = "{{{langname}}} adverbs that indicate the motive or other background information for an action.",
parents = {"adverbs"},
}
labels["active verbs"] = {
description = "{{{langname}}} verbs that indicate an activity",
parents = {"کارەکان"},
}
labels["adjective concords"] = {
description = "{{{langname}}} concords that are prefixed to adjective stems.",
parents = {"concords"},
}
labels["ھاوەڵناوەکان"] = {
description = "{{{langname}}} terms that give attributes to nouns, extending their definitions.",
parents = {"لێماکان"},
}
labels["adverbial accusatives"] = {
description = "Accusative case-forms in {{{langname}}} used as adverbs.",
parents = {"adverbs"},
}
labels["adverbs"] = {
description = "{{{langname}}} terms that modify clauses, sentences and phrases directly.",
parents = {"لێماکان"},
}
labels["affixes"] = {
description = "Morphemes attached to existing {{{langname}}} words.",
parents = {"morphemes"},
}
labels["agent nouns"] = {
description = "{{{langname}}} nouns that denote an agent that performs the action denoted by the verb from which the noun is derived.",
parents = {"ناوەکان"},
}
labels["ambipositions"] = {
description = "{{{langname}}} adpositions that can occur either before or after their objects.",
parents = {"لێماکان"},
}
labels["ambitransitive verbs"] = {
description = "{{{langname}}} verbs that may or may not direct actions, occurrences or states to grammatical objects.",
parents = {"verbs", "transitive verbs", "intransitive verbs"},
}
labels["animal commands"] = {
description = "{{{langname}}} words used to communicate with animals.",
parents = {"interjections"},
}
labels["articles"] = {
description = "{{{langname}}} terms that indicate and specify nouns.",
parents = {"determiners"},
}
labels["aspect adverbs"] = {
description = "{{{langname}}} adverbs that express [[w:Grammatical aspect|grammatical aspect]], describing the flow of time in relation to a statement.",
parents = {"adverbs"},
}
for _, pos in ipairs(diminutive_augmentative_poses) do
labels["augmentative " .. pos] = {
description = "{{{langname}}} " .. pos .. " that are derived from a base word to convey big size or big intensity.",
parents = {pos},
}
end
labels["attenuative verbs"] = {
description = "{{{langname}}} verbs that indicate that an action or event is performed or takes place gently, lightly, partially, perfunctorily or to an otherwise reduced extent.",
parents = {"کارەکان"},
}
labels["autobenefactive verbs"] = {
description = "{{{langname}}} verbs that indicate that the agent of an action is also its benefactor.",
parents = {"کارەکان"},
}
labels["automative verbs"] = {
description = "{{{langname}}} verbs that indicate actions directed at or a change of state of the grammatical subject.",
parents = {"کارەکان"},
}
labels["auxiliary verbs"] = {
description = "{{{langname}}} verbs that provide additional conjugations for other verbs.",
parents = {"کارەکان"},
}
labels["biaspectual verbs"] = {
description = "{{{langname}}} verbs that can be both imperfective and perfective.",
parents = {"کارەکان"},
}
labels["causative verbs"] = {
description = "{{{langname}}} verbs that express causing actions or states rather than performing or being them directly. Use this only for separate verbs (as opposed to causative forms that are part of the inflection of verbs).",
parents = {"کارەکان"},
}
labels["circumfixes"] = {
description = "Affixes attached to both the beginning and the end of {{{langname}}} words, functioning together as single units.",
parents = {"morphemes"},
}
labels["circumpositions"] = {
description = "{{{langname}}} adpositions that appear on both sides of their objects.",
parents = {"لێماکان"},
}
labels["classifiers"] = {
description = "{{{langname}}} terms that classify nouns according to their meanings.",
parents = {"لێماکان"},
}
labels["clitics"] = {
description = "{{{langname}}} morphemes that function as independent words, but are always attached to another word.",
parents = {"morphemes"},
}
for _, pos in ipairs { "nouns", "suffixes" } do
labels["collective " .. pos] = {
description = "{{{langname}}} " .. pos .. " that indicate groups of related things or beings, without the need of grammatical pluralization.",
parents = {pos},
}
end
labels["combining forms"] = {
description = "Forms of {{{langname}}} words that do not occur independently, but are used when joined with other words.",
parents = {"morphemes"},
}
labels["comparable adjectives"] = {
description = "{{{langname}}} adjectives that can be inflected to display different degrees of comparison.",
parents = {"ھاوەڵناوەکان"},
}
labels["comparable adverbs"] = {
description = "{{{langname}}} adverbs that can be inflected to display different degrees of comparison.",
parents = {"adverbs"},
}
labels["comparative-only adjectives"] = {
description = "{{{langname}}} adjectives that are only used in their comparative forms.",
parents = {"ھاوەڵناوەکان"},
}
labels["completive verbs"] = {
description = "{{{langname}}} verbs which refer to the completion of an action which has already commenced or which has already been performed upon a subset of the entities which it affects.",
parents = {"کارەکان"},
}
labels["concords"] = {
description = "{{{langname}}} prefixes attached to words to show agreement with a noun or pronoun.",
parents = {"prefixes"},
}
labels["concrete verbs"] = {
description = "{{{langname}}} concrete verbs refer to a verbal aspect in verbs of motion that is unidirectional (as opposed to multidirectional), a definitely directed motion, or a single, completed action (instead of a repeated action or series of actions). Concrete verbs may be either imperfective or perfective.",
additional = "See also [[concrete verb]].",
parents = {"کارەکان"},
}
labels["conjunctions"] = {
description = "{{{langname}}} terms that connect words, phrases or clauses together.",
parents = {"لێماکان"},
}
labels["conjunctive adverbs"] = {
description = "{{{langname}}} adverbs that connect two independent clauses together.",
parents = {"adverbs"},
}
labels["continuative verbs"] = {
description = "{{{langname}}} verbs that express continuing action.",
parents = {"کارەکان"},
}
labels["control verbs"] = {
description = "{{{langname}}} verbs that take multiple arguments, one of which is another verb. One of the control verb's arguments is syntactically both an argument of the control verb and an argument of the other verb.",
parents = {"کارەکان"},
}
labels["cooperative verbs"] = {
description = "{{{langname}}} verbs that indicate cooperation",
parents = {"کارەکان"},
}
labels["coordinating conjunctions"] = {
description = "{{{langname}}} conjunctions that indicate equal syntactic importance between connected items.",
parents = {"conjunctions"},
}
labels["copulative verbs"] = {
description = "{{{langname}}} verbs that may take adjectives as their complement.",
parents = {"کارەکان"},
}
labels["ناوە ژماردەنییەکان"] = {
description = "ناوە ژماردەنییە {{{langname}}}یەکان کە دەتوانرێت ڕاستەوخۆ بە ژمارەیی بپێورێت.",
parents = {"ناوەکان"},
}
labels["ناوە تایبەتەکان"] = {
description = "ناوە تایبەتە {{{langname}}}یەکان کە دەتوانرێت ڕاستەوخۆ بە ژمارەیی بپێورێت.",
parents = {"ناوەکان"},
}
labels["countable numerals"] = {
description = "{{{langname}}} numerals that can be quantified directly by other numerals.",
parents = {"numerals"},
}
labels["countable suffixes"] = {
description = "{{{langname}}} suffixes that can be used to form nouns that can be quantified directly by numerals.",
parents = {"numerals"},
}
labels["counters"] = {
description = "{{{langname}}} terms that combine with numerals to express quantity of nouns.",
parents = {"لێماکان"},
}
labels["cumulative verbs"] = {
description = "{{{langname}}} verbs which indicate that an action or event gradually yields a certain or significant quantity or effect.",
parents = {"کارەکان"},
}
labels["degree adverbs"] = {
description = "{{{langname}}} adverbs that express a particular degree to which the word they modify applies.",
parents = {"adverbs"},
}
labels["delimitative verbs"] = {
description = "{{{langname}}} verbs which indicate that an action or event is performed or takes place briefly or to an otherwise reduced extent.",
parents = {"کارەکان"},
}
labels["demonstrative adjectives"] = {
description = "{{{langname}}} adjectives that refer to nouns, comparing them to external references.",
parents = {"adjectives", {name = "demonstrative pro-forms", sort = "adjectives"}},
}
labels["demonstrative adverbs"] = {
description = "{{{langname}}} adverbs that refer to other adverbs, comparing them to external references.",
parents = {"adverbs", {name = "demonstrative pro-forms", sort = "adverbs"}},
}
labels["denominal verbs"] = { -- in [[Appendix:Glossary]]; "denominative" more frequent?
description = "{{{langname}}} verbs that derive from nouns.",
parents = { "verbs" },
}
labels["demonstrative determiners"] = {
description = "{{{langname}}} determiners that refer to nouns, comparing them to external references.",
parents = {"determiners", {name = "demonstrative pro-forms", sort = "determiners"}},
}
labels["demonstrative pronouns"] = {
description = "{{{langname}}} pronouns that refer to nouns, comparing them to external references.",
parents = {"pronouns", {name = "demonstrative pro-forms", sort = "pronouns"}},
}
labels["deponent verbs"] = {
description = "{{{langname}}} verbs that have active meanings but are not conjugated in the active voice.",
parents = {"کارەکان"},
}
labels["derivational prefixes"] = {
description = "{{{langname}}} prefixes that are used to create new words.",
parents = {"prefixes"},
}
labels["derivational suffixes"] = {
description = "{{{langname}}} suffixes that are used to create new words.",
parents = {"suffixes"},
}
labels["derivative verbs"] = {
description = "{{{langname}}} verbs that are derived from nouns and adjectives.",
parents = {"کارەکان"},
}
labels["desiderative verbs"] = {
description = "{{{langname}}} verbs with the following morphology: verbal root xxx + [[desiderative]] affix, and the following semantics: to wish to do the action xxx.",
parents = {"کارەکان"},
}
labels["determinatives"] = {
description = "{{{langname}}} terms that indicate the general class to which the following logogram belongs.",
parents = {"لێماکان"},
}
labels["determiners"] = {
description = "{{{langname}}} terms that narrow down, within the conversational context, the referent of the following noun.",
parents = {"لێماکان"},
}
labels["diminutiva tantum"] = {
description = "{{{langname}}} nouns or noun senses that are mostly or exclusively used in the diminutive form.",
parents = {"ناوەکان"},
}
for _, pos in ipairs(diminutive_augmentative_poses) do
labels["diminutive " .. pos] = {
description = "{{{langname}}} " .. pos .. " that are derived from a base word to convey endearment, small size or small intensity.",
parents = {pos},
}
end
labels["discourse particles"] = {
description = "{{{langname}}} particles that manage the flow and structure of discourse.",
parents = {"particles"},
}
labels["distributive verbs"] = {
description = "{{{langname}}} verbs which indicate that an action or event involves multiple participants or a large quantity of an uncountable mass, usually as the grammatical subject in the case of intransitive verbs and as the grammatical object in the case of transitive verbs.",
parents = {"کارەکان"},
}
labels["ditransitive verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states of two grammatical objects simultaneously, one direct and one indirect.",
parents = {"verbs", "transitive verbs"},
}
labels["dualia tantum"] = {
description = "{{{langname}}} nouns that are mostly or exclusively used in the dual form.",
parents = {"ناوەکان"},
}
labels["duration adverbs"] = {
description = "{{{langname}}} adverbs that express duration in time.",
parents = {"time adverbs"},
}
labels["ergative verbs"] = {
description = "{{{langname}}} [[Appendix:Glossary#ergative|ergative verb]]s: intransitive verbs that become causatives when used transitively.",
parents = {"verbs", "intransitive verbs", "transitive verbs"},
}
labels["excessive verbs"] = {
description = "{{{langname}}} verbs that indicate that an action is performed to an excessive extent.",
parents = {"کارەکان"},
}
labels["enclitics"] = {
description = "{{{langname}}} clitics that attach to the preceding word.",
parents = {"clitics"},
}
labels["nouns with other-gender equivalents"] = {
description = "{{{langname}}} nouns that refer to gendered concepts (e.g. [[actor]] vs. [[actress]], [[king]] vs. [[queen]]) and have corresponding other-gender equivalent terms.",
parents = {"ناوەکان"},
}
labels["female equivalent nouns"] = {
description = "{{{langname}}} nouns that refer to female beings with the same characteristics as the base noun.",
parents = {"nouns with other-gender equivalents"},
}
labels["neuter equivalent nouns"] = {
description = "{{{langname}}} nouns that refer to neuter beings with the same characteristics as the base noun.",
parents = {"nouns with other-gender equivalents"},
}
labels["female equivalent suffixes"] = {
description = "{{{langname}}} suffixes that refer to female beings with the same characteristics as the base suffix.",
parents = {"noun-forming suffixes"},
}
labels["focus adverbs"] = {
description = "{{{langname}}} adverbs that indicate [[w:Focus (linguistics)|focus]] within the sentence.",
parents = {"adverbs"},
}
labels["frequency adverbs"] = {
description = "{{{langname}}} adverbs that express repetition with a certain frequency or interval.",
parents = {"time adverbs"},
}
labels["frequentative verbs"] = {
description = "{{{langname}}} verbs that express repeated action.",
parents = {"کارەکان"},
}
labels["general pronouns"] = {
description = "{{{langname}}} pronouns that refer to all persons, things, abstract ideas and their characteristics.",
parents = {"pronouns"},
}
labels["generational moieties"] = {
description = "{{{langname}}} moieties that alternate every generation.",
parents = {"moieties"},
}
labels["ideophones"] = {
description = "{{{langname}}} terms that evoke an idea, especially a sensation or impression, with a sound.",
parents = {"لێماکان"},
}
labels["imperfective verbs"] = {
description = "{{{langname}}} verbs that express actions considered as ongoing or continuous, as opposed to completed events.",
parents = {"کارەکان"},
}
labels["impersonal verbs"] = {
description = "{{{langname}}} verbs that do not indicate actions, occurrences or states of any specific grammatical subject.",
parents = {"کارەکان"},
}
labels["inchoative verbs"] = {
description = "{{{langname}}} verbs that indicate the beginning of an action or event.",
parents = {"کارەکان"},
}
labels["indefinite adjectives"] = {
description = "{{{langname}}} adjectives that refer to unspecified adjective meanings.",
parents = {"adjectives", {name = "indefinite pro-forms", sort = "adjectives"}},
}
labels["indefinite adverbs"] = {
description = "{{{langname}}} adverbs that refer to unspecified adverbial meanings.",
parents = {"adverbs", {name = "indefinite pro-forms", sort = "adverbs"}},
}
labels["indefinite determiners"] = {
description = "{{{langname}}} determiners that designate an unidentified noun.",
parents = {"determiners", {name = "indefinite pro-forms", sort = "determiners"}},
}
labels["indefinite pronouns"] = {
description = "{{{langname}}} pronouns that refer to unspecified nouns.",
parents = {"pronouns", {name = "indefinite pro-forms", sort = "pronouns"}},
}
labels["infixes"] = {
description = "Affixes inserted inside {{{langname}}} words.",
parents = {"morphemes"},
}
labels["inflectional prefixes"] = {
description = "{{{langname}}} prefixes that are used as inflectional beginnings in noun, adjective or verb paradigms.",
parents = {"prefixes"},
}
labels["inflectional suffixes"] = {
description = "{{{langname}}} suffixes that are used as inflectional endings in noun, adjective or verb paradigms.",
parents = {"suffixes"},
}
labels["intensive verbs"] = {
description = "{{{langname}}} verbs which indicate that an action is performed vigorously, enthusiastically, forcefully or to an otherwise enlarged extent.",
parents = {"کارەکان"},
}
labels["interfixes"] = {
description = "Affixes used to join two {{{langname}}} words or morphemes together.",
parents = {"morphemes"},
}
labels["interjections"] = {
description = "{{{langname}}} terms that express emotions, sounds, etc. as exclamations.",
parents = {"لێماکان"},
}
labels["interrogative adjectives"] = {
description = "{{{langname}}} adjectives that indicate questions.",
parents = {"adjectives", {name = "interrogative pro-forms", sort = "adjectives"}},
}
labels["interrogative adverbs"] = {
description = "{{{langname}}} adverbs that indicate questions.",
parents = {"adverbs", {name = "interrogative pro-forms", sort = "adverbs"}},
}
labels["interrogative determiners"] = {
description = "{{{langname}}} determiners that indicate questions.",
parents = {"determiners", {name = "interrogative pro-forms", sort = "determiners"}},
}
labels["interrogative particles"] = {
description = "{{{langname}}} particles that indicate questions.",
parents = {"particles", {name = "interrogative pro-forms", sort = "particles"}},
}
labels["interrogative pronouns"] = {
description = "{{{langname}}} pronouns that indicate questions.",
parents = {"pronouns", {name = "interrogative pro-forms", sort = "pronouns"}},
}
labels["intransitive verbs"] = {
description = "{{{langname}}} verbs that don't require any grammatical objects.",
parents = {"کارەکان"},
}
labels["iterative verbs"] = {
description = "{{{langname}}} verbs that express the repetition of an event.",
parents = {"کارەکان"},
}
labels["location adverbs"] = {
description = "{{{langname}}} adverbs that indicate location.",
parents = {"adverbs"},
}
labels["male equivalent nouns"] = {
description = "{{{langname}}} nouns that refer to male beings with the same characteristics as the base noun.",
parents = {"nouns with other-gender equivalents"},
}
labels["manner adverbs"] = {
description = "{{{langname}}} adverbs that indicate the manner, way or style in which an action is performed.",
parents = {"adverbs"},
}
labels["modal adverbs"] = {
description = "{{{langname}}} adverbs that express [[w:Linguistic modality|linguistic modality]], indicating the mood or attitude of the speaker with respect to what is being said.",
parents = {"sentence adverbs"},
}
labels["modal particles"] = {
description = "{{{langname}}} particles that reflect the mood or attitude of the speaker, without changing the basic meaning of the sentence.",
parents = {"particles"},
}
labels["modal verbs"] = {
description = "{{{langname}}} verbs that indicate [[grammatical mood]].",
parents = {"auxiliary verbs"},
}
labels["moieties"] = {
description = "{{{langname}}} pairs of abstract categories separating people and the environment.",
parents = {"لێماکان"},
}
labels["momentane verbs"] = {
description = "{{{langname}}} verbs that express a sudden and brief action.",
parents = {"کارەکان"},
}
labels["morphemes"] = {
description = "{{{langname}}} word-elements used to form full words.",
parents = {"لێماکان"},
}
labels["multiword terms"] = {
description = "{{{langname}}} lemmas that are an [[WT:CFI#Idiomaticity|idiomatic]] combination of multiple words.",
parents = {"لێماکان"},
}
labels["negative verbs"] = {
description = "{{{langname}}} verbs that indicate the lack of an action.",
parents = {"کارەکان"},
}
labels["negative particles"] = {
description = "{{{langname}}} particles that indicate negation.",
parents = {"particles"},
}
labels["negative pronouns"] = {
description = "{{{langname}}} pronouns that refer to negative or non-existent references.",
parents = {"pronouns"},
}
labels["neutral verbs"] = {
description = "{{{langname}}} verbs that indicate either or both an activity or a result of an activity",
parents = {"کارەکان"},
}
labels["nominalized adjectives"] = {
description = "{{{langname}}} adjectives that are used as nouns.",
parents = {"nouns", "adjectives"},
}
labels["non-constituents"] = {
description = "{{{langname}}} terms that are not grammatical [[constituent#Noun|constituents]], and therefore need to be combined with additional terms to form a complete phrase.",
parents = {"phrases"},
}
labels["noun prefixes"] = {
description = "{{{langname}}} prefixes attached to a noun that display its noun class.",
parents = {"prefixes"},
}
labels["ناوەکان"] = {
description = "{{{langname}}} terms that indicate people, beings, things, places, phenomena, qualities or ideas.",
parents = {"لێماکان"},
}
labels["nouns by classifier"] = {
description = "{{{langname}}} nouns organized by the classifier they are used with.",
parents = {{name = "nouns", sort = "classifier"}},
}
labels["numerals"] = {
description = "{{{langname}}} terms that quantify nouns.",
parents = {"لێماکان"},
}
labels["object concords"] = {
description = "{{{langname}}} concords used to show the grammatical object.",
parents = {"concords"},
}
labels["object pronouns"] = {
description = "{{{langname}}} pronouns that refer to grammatical objects.",
parents = {"pronouns"},
}
labels["particles"] = {
description = "{{{langname}}} terms that do not belong to any of the inflected grammatical word classes, often lacking their own grammatical functions and forming other parts of speech or expressing the relationship between clauses.",
parents = {"لێماکان"},
}
labels["passive verbs"] = {
description = "{{{langname}}} verbs that are usually used in passive voice.",
parents = {"کارەکان"},
}
labels["perfective verbs"] = {
description = "{{{langname}}} verbs that express actions considered as completed events, as opposed to ongoing or continuous.",
parents = {"کارەکان"},
}
labels["personal pronouns"] = {
description = "{{{langname}}} pronouns that are used as substitutes for known nouns.",
parents = {"pronouns"},
}
labels["phrasal verbs"] = {
description = "{{{langname}}} verbs accompanied by particles, such as prepositions and adverbs.",
parents = {"verbs", "phrases"},
}
labels["phrasal prepositions"] = {
description = "{{{langname}}} prepositions formed with combinations of other terms.",
parents = {"prepositions", "phrases"},
}
labels["pluralia tantum"] = {
description = "{{{langname}}} nouns that are mostly or exclusively used in the plural form.",
parents = {"ناوەکان"},
}
labels["point-in-time adverbs"] = {
description = "{{{langname}}} adverbs that reference a specific point in time, e.g. {{m|en|yesterday}}, {{m+|es|anoche||last night}} or {{m+|hu|egykor||at one o'clock}}.",
parents = {"time adverbs"},
}
labels["possessable nouns"] = {
description = "{{{langname}}} nouns can have their possession indicated directly by possessive pronouns.",
parents = {"ناوەکان"},
umbrella = {
description = "Categories with nouns that can have their possession indicated directly by possessive pronouns and, in some languages, be transformed into adjectives.",
parents = {"Lemmas subcategories by language"},
breadcrumb = "Possessable nouns by language",
},
}
labels["possessional adjectives"] = {
description = "{{{langname}}} adjectives that indicate that a noun is in possession of something.",
parents = {"ھاوەڵناوەکان"},
}
labels["possessive adjectives"] = {
description = "{{{langname}}} adjectives that indicate ownership.",
parents = {"ھاوەڵناوەکان"},
}
labels["possessive concords"] = {
description = "{{{langname}}} concords used to show possession.",
parents = {"concords"},
}
labels["possessive determiners"] = {
description = "{{{langname}}} determiners that indicate ownership.",
parents = {"determiners"},
}
labels["possessive pronouns"] = {
description = "{{{langname}}} pronouns that indicate ownership.",
parents = {"pronouns"},
}
labels["postpositional phrases"] = {
description = "{{{langname}}} phrases headed by a postposition.",
parents = {"phrases", "postpositions"},
}
labels["postpositions"] = {
description = "{{{langname}}} adpositions that are placed after their objects.",
parents = {"لێماکان"},
}
labels["predicatives"] = {
description = "{{{langname}}} elements of the predicate that supplement the subject or object of a sentence via the verb.",
parents = {"لێماکان"},
}
labels["prefixes"] = {
description = "Affixes attached to the beginning of {{{langname}}} words.",
parents = {"morphemes"},
}
labels["prepositional phrases"] = {
description = "{{{langname}}} phrases headed by a preposition.",
parents = {"phrases", "prepositions"},
}
labels["prepositions"] = {
description = "{{{langname}}} adpositions that are placed before their objects.",
parents = {"لێماکان"},
}
labels["ablative prepositions"] = {
description = "{{{langname}}} prepositions that cause the succeeding noun to be in the ablative case.",
parents = {"prepositions"},
}
labels["accusative prepositions"] = {
description = "{{{langname}}} prepositions that cause the succeeding noun to be in the accusative case.",
parents = {"prepositions"},
}
labels["dative prepositions"] = {
description = "{{{langname}}} prepositions that cause the succeeding noun to be in the dative case.",
parents = {"prepositions"},
}
labels["genitive prepositions"] = {
description = "{{{langname}}} prepositions that cause the succeeding noun to be in the genitive case.",
parents = {"prepositions"},
}
labels["instrumental prepositions"] = {
description = "{{{langname}}} prepositions that cause the succeeding noun to be in the instrumental case.",
parents = {"prepositions"},
}
labels["matrilineal moieties"] = {
description = "{{{langname}}} moieties inherited from an individual's mother.",
parents = {"moieties"},
}
labels["nominative prepositions"] = {
description = "{{{langname}}} prepositions that cause the succeeding noun to be in the nominative case.",
parents = {"prepositions"},
}
labels["patrilineal moieties"] = {
description = "{{{langname}}} moieties inherited from an individual's father.",
parents = {"moieties"},
}
labels["pejorative suffixes"] = {
description = "{{{langname}}} suffixes that [[belittle]] (lessen in value).",
parents = {"suffixes"},
}
labels["prepositional prepositions"] = {
description = "{{{langname}}} prepositions that cause the succeeding noun to be in the prepositional case.",
parents = {"prepositions"},
}
labels["prenouns"] = {
description = "{{{langname}}} prefixes of various kinds that are attached to nouns.",
parents = {"prefixes"},
}
labels["preverbs"] = {
description = "{{{langname}}} prefixes of various kinds that are attached to verbs.",
parents = {"prefixes"},
}
labels["privative verbs"] = {
description = "{{{langname}}} verbs that indicate that the grammatical object is deprived of something or that something is removed from the object.",
parents = {"کارەکان"},
}
labels["pronominal adverbs"] = {
description = "{{{langname}}} adverbs that are formed by combining a pronoun with a preposition.",
parents = {"adverbs", "prepositions", "pronouns"},
}
labels["pronominal concords"] = {
description = "{{{langname}}} concords that are prefixed to pronominal stems.",
parents = {"concords"},
}
labels["pronouns"] = {
description = "{{{langname}}} terms that refer to and substitute nouns.",
parents = {"لێماکان"},
}
labels["proper nouns"] = {
description = "{{{langname}}} nouns that indicate individual entities, such as names of persons, places or organizations.",
parents = {"ناوەکان"},
}
labels["punctual adverbs"] = {
description = "{{{langname}}} adverbs that express a single point or span in time.",
parents = {"time adverbs"},
}
labels["raising verbs"] = {
description = "{{{langname}}} verbs that, in a matrix or main clause, take an argument from an embedded or subordinate clause; in other words, a raising verb appears with a syntactic argument that is not its semantic argument, but is rather the semantic argument of an embedded predicate.",
parents = {"کارەکان"},
}
labels["reciprocal pronouns"] = {
description = "{{{langname}}} pronouns that refer back to a plural subject and express an action done in two or more directions.",
parents = {"pronouns", "personal pronouns"},
}
labels["reciprocal verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states directed from multiple subjects to each other.",
parents = {"کارەکان"},
}
labels["reflexive pronouns"] = {
description = "{{{langname}}} pronouns that refer back to the subject.",
parents = {"pronouns", "personal pronouns"},
}
labels["reflexive verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states directed from the grammatical subjects to themselves.",
parents = {"کارەکان"},
}
labels["relational adjectives"] = {
description = "{{{langname}}} adjectives that stand in place of a noun when modifying another noun.",
parents = {"ھاوەڵناوەکان"},
}
labels["relational nouns"] = {
description = "{{{langname}}} nouns used to indicate a relation between other two nouns by means of possession.",
parents = {"ناوەکان"},
}
labels["relative adjectives"] = {
description = "{{{langname}}} adjectives used to indicate [[relative clause]]s.",
parents = {"adjectives", {name = "relative pro-forms", sort = "adjectives"}},
}
labels["relative adverbs"] = {
description = "{{{langname}}} adverbs used to indicate [[relative clause]]s.",
parents = {"adverbs", {name = "relative pro-forms", sort = "adverbs"}},
}
labels["relative determiners"] = {
description = "{{{langname}}} determiners used to indicate [[relative clause]]s.",
parents = {"determiners", {name = "relative pro-forms", sort = "determiners"}},
}
labels["relative concords"] = {
description = "{{{langname}}} concords that are prefixed to relative stems.",
parents = {"concords"},
}
labels["relative pronouns"] = {
description = "{{{langname}}} pronouns used to indicate [[relative clause]]s.",
parents = {"pronouns", {name = "relative pro-forms", sort = "pronouns"}},
}
labels["relatives"] = {
description = "{{{langname}}} terms that give attributes to nouns, acting grammatically as relative clauses.",
parents = {"لێماکان"},
}
labels["repetitive verbs"] = {
description = "{{{langname}}} verbs that indicate actions or events which are performed or occur again, anew or differently.",
parents = {"کارەکان"},
}
labels["resultative verbs"] = {
description = "{{{langname}}} verbs that indicate a result of some action",
parents = {"کارەکان"},
}
labels["reversative verbs"] = {
description = "{{{langname}}} verbs that indicate that the reversal or undoing of an action, event or state.",
parents = {"کارەکان"},
}
labels["saturative verbs"] = {
description = "{{{langname}}} verbs which indicate that an action is performed to the point of saturation or satisfaction.",
parents = {"کارەکان"},
}
labels["semelfactive verbs"] = {
description = "{{{langname}}} verbs that are punctual (instantaneous, momentive), perfective (treated as a unitary whole with no explicit internal temporal structure), and telic (having a boundary out of which the activity cannot be said to have taken place or continue).",
parents = {"کارەکان"},
}
labels["sentence adverbs"] = {
description = "{{{langname}}} adverbs that modify an entire clause or sentence.",
parents = {"adverbs"},
}
labels["sequence adverbs"] = {
description = "{{{langname}}} conjunctive adverbs that express sequence in space or time.",
parents = {"conjunctive adverbs"},
}
labels["simulfixes"] = {
description = "Affixes replacing positions in {{{langname}}} words.",
parents = {"morphemes"},
}
labels["singulative nouns"] = {
description = "{{{langname}}} nouns that indicate a single item of a group of related things or beings.",
parents = {"ناوەکان"},
}
labels["singularia tantum"] = {
description = "{{{langname}}} nouns that are mostly or exclusively used in the singular form.",
parents = {"ناوەکان"},
}
labels["stative verbs"] = {
description = "{{{langname}}} verbs that define a state with no or insignificant internal dynamics.",
parents = {"کارەکان"},
}
labels["stems"] = {
description = "Morphemes from which {{{langname}}} words are formed.",
parents = {"morphemes"},
}
labels["subordinating conjunctions"] = {
description = "{{{langname}}} conjunctions that indicate relations of syntactic dependence between connected items.",
parents = {"conjunctions"},
}
labels["subject concords"] = {
description = "{{{langname}}} concords used to show the grammatical subject.",
parents = {"concords"},
}
labels["subject pronouns"] = {
description = "{{{langname}}} pronouns that refer to grammatical subjects.",
parents = {"pronouns"},
}
labels["suffixes"] = {
description = "Affixes attached to the end of {{{langname}}} words.",
parents = {"morphemes"},
}
labels["splitting verbs"] = {
description = "{{{langname}}} bisyllabic verbs that obligatorily split around a direct object or pronoun.",
parents = {"کارەکان"},
}
labels["terminative verbs"] = {
description = "{{{langname}}} verbs that indicate that an action or event ceases.",
parents = {"کارەکان"},
}
labels["time adverbs"] = {
description = "{{{langname}}} adverbs that indicate time.",
parents = {"adverbs"},
}
labels["transfixes"] = {
description = "Discontinuous affixes inserted within a word root.",
parents = {"morphemes"},
}
labels["transformative verbs"] = {
description = "{{{langname}}} verbs that indicate a change of state or nature, in the subject for intransitive verbs and in the object for transitive verbs.",
parents = {"کارەکان"},
}
labels["transitive verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states directed to one or more grammatical objects.",
parents = {"کارەکان"},
}
labels["uncomparable adjectives"] = {
description = "{{{langname}}} adjectives that are not inflected to display different degrees of comparison.",
parents = {"ھاوەڵناوەکان"},
}
labels["uncomparable adverbs"] = {
description = "{{{langname}}} adverbs that are not inflected to display different degrees of comparison.",
parents = {"adverbs"},
}
labels["ناوە ژماردەنییەکان"] = {
description = "{{{langname}}} nouns that indicate qualities, ideas, unbounded mass or other abstract concepts that cannot be quantified directly by numerals.",
parents = {"ناوەکان"},
}
labels["uncountable numerals"] = {
description = "{{{langname}}} numerals that cannot be quantified directly by other numerals.",
parents = {"numerals"},
}
labels["uncountable proper nouns"] = {
description = "{{{langname}}} proper nouns that cannot be quantified directly by numerals.",
parents = {"proper nouns"},
}
labels["uncountable suffixes"] = {
description = "{{{langname}}} suffixes that can be used to form nouns that cannot be quantified directly by numerals.",
parents = {"numerals"},
}
labels["unpossessable nouns"] = {
description = "{{{langname}}} nouns that cannot have their possession indicated directly by possessive pronouns.",
parents = {"ناوەکان"},
umbrella = {
description = "Categories with nouns that cannot have their possession indicated directly by possessive pronouns or, in some languages, be transformed into adjectives.",
parents = {"Lemmas subcategories by language"},
breadcrumb = "Unpossessable nouns by language",
},
}
labels["verbal nouns"] = {
description = "{{{langname}}} nouns morphologically related to a verb and similar to it in meaning.",
parents = {"ناوەکان"},
}
labels["verbal adjectives"] = {
description = "{{{langname}}} adjectives describing the condition or state resulting from the action of the corresponding verb.",
parents = {"ھاوەڵناوەکان"},
}
labels["کارەکان"] = {
description = "{{{langname}}} terms that indicate actions, occurrences or states.",
parents = {"لێماکان"},
}
labels["verbs of movement"] = {
description = "{{{langname}}} verbs that indicate physical movement of the grammatical subject across a trajectory, with a starting point and an endpoint.",
parents = {"کارەکان"},
}
-- Add "POS-forming suffixes".
local poses_derived_by_suffix = {
"adjective", "adverb", "noun", "verb",
}
for _, pos in pairs(poses_derived_by_suffix) do
labels[pos .. "-forming suffixes"] = {
description = "{{{langname}}} suffixes that are used to derive " .. pos .. "s from other words.",
parents = {"derivational suffixes"},
}
end
local labels2 = {}
-- Add "reconstructed" subcategories; add 'umbrella_parents' key if not
-- already present.
for key, data in pairs(labels) do
labels2[key] = data
if not data.umbrella_parents then
data.umbrella_parents = "Lemmas subcategories by language"
end
labels2["reconstructed " .. key] = {
description = "{{{langname}}} " .. key .. " that have been linguistically [[Wiktionary:Reconstructed terms|reconstructed]].",
umbrella_parents = "Lemmas subcategories by language",
parents = {key, {name = "reconstructed terms", sort = key}}
}
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["Lemmas subcategories by language"] = {
description = "Umbrella categories covering topics related to lemmas.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"Umbrella metacategories",
{name = "لێماکان", is_label = true, sort = " "},
},
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
-- Handler for e.g. [[:Category:English phrasal verbs with particle (around)]].
table.insert(handlers, function(data)
local particle = data.label:match("^phrasal verbs with particle %((.-)%)$")
if particle then
local tagged_text = require("Module:script utilities").tag_text(particle, data.lang, nil, "term")
local link = require("Module:links").full_link({ term = particle, lang = data.lang }, "term")
return {
description = "{{{langname}}} {{w|phrasal verb}}s using the particle " .. link .. ".",
displaytitle = "{{{langname}}} phrasal verbs with particle (" .. tagged_text .. ")",
breadcrumb = tagged_text,
parents = {{ name = "phrasal verbs", sort = particle }},
umbrella = false,
}
end
end)
return {LABELS = labels2, RAW_CATEGORIES = raw_categories, HANDLERS = handlers}
83ua8kolrila27ik4bitk7437mdbair
مۆدیوول:category tree/modules
828
9313
36932
34753
2026-08-18T00:10:49Z
Ghybu
12
بەپێی زمان (by language)
36932
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local raw_handlers = {}
local insert = table.insert
local pattern_escape = require("Module:string utilities").pattern_escape
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["modules"] = {
description = "{{{langname}}} [[Wiktionary:Modules|modules]], which contain Lua code to create and manage entries.",
umbrella = {
parents = {{name = "Modules", sort = " "}},
breadcrumb = "بەپێی زمان",
},
parents = {{name = "{{{langcat}}}", raw = true}},
}
labels["data modules"] = {
description = "{{{langname}}} [[Wiktionary:Modules|modules]] containing data used by other modules.",
umbrella = {
parents = {{name = "Data modules", sort = " "}},
breadcrumb = "بەپێی زمان",
},
breadcrumb = "data",
parents = {"modules"},
}
labels["dialect synonyms data modules"] = {
description = "{{{langname}}} [[Wiktionary:Modules|modules]] containing data used by {{tl|dialect synonyms}}.",
umbrella = {
parents = {{name = "Dialect synonyms data modules", sort = " "}},
breadcrumb = "بەپێی زمان",
},
breadcrumb = "dialect synonyms",
parents = {"data modules"},
}
labels["inflection modules"] = {
description = "{{{langname}}} [[inflection]] [[Wiktionary:Modules|modules]], which contain Lua code for generating conjugation and declension tables.",
umbrella = {
parents = {{name = "Inflection modules", sort = " "}},
breadcrumb = "بەپێی زمان",
},
breadcrumb = "inflection",
parents = {"modules", {name = "inflection-table templates", sort = " "}},
}
labels["testcase modules"] = {
description = "{{{langname}}} [[testcase]] [[Wiktionary:Modules|modules]], which contain Lua code for testing other modules.",
umbrella = {
parents = {{name = "Testcase modules", sort = " "}},
breadcrumb = "بەپێی زمان",
},
breadcrumb = "testcase",
parents = {"modules"},
}
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
--[=[
Correctly defining a new module type here:
1. The breadcrumb generally does not need to be given because there is code at the bottom of this file
to generate the breadcrumb in a smart fashion by chopping off a suffix derived from the parent or any of
its ancestors.
2. Module types can be nested under other module types, but also list them directly under 'Modules' as a
secondary parent. (This violates a principle of non-duplication of categories but makes it much easier to
locate a given module type.)
]=]
raw_categories["Modules"] = {
description = "This is a general holder category for modules.",
additional = "For more information on what modules are and how they work, see [[Wiktionary:Scribunto]]. For a complete list of all modules, see [[Special:PrefixIndex/Module:|here]].",
parents = {"Category:Wiktionary"},
}
raw_categories["Uncategorized modules"] = {
description = "Uncategorized modules.",
additional = "Modules are placed here by [[Module:documentation]] under certain circumstances. See the documentation of that module for more info.",
parents = { {name = "Modules", sort = " "} },
}
raw_categories["Appendix modules"] = {
preceding = "{{also|:Category:Appendix templates}}",
description = "Modules with functions that generate content for or extract information from pages in the Appendix namespace.",
parents = { "Modules" },
}
raw_categories["Bot support modules"] = {
description = "Modules for supporting individual bot accounts.",
parents = { "Modules" },
}
raw_categories["Category modules"] = {
preceding = "{{also|:Category:Categorization templates|:Category:Category templates}}",
description = "Modules for adding categories to pages or generating the description and subcategories of category pages.",
parents = { "Modules" },
}
raw_categories["Character info modules"] = {
preceding = "{{also|:Category:Character info templates}}",
description = "Modules containing information on individual characters, or containing functions generating such information.",
parents = { "Modules" },
}
raw_categories["Character insertion modules"] = {
preceding = "{{also|:Category:Character insertion templates}}",
description = "Modules that implement templates that provide easier ways to type characters that are not found in most keyboard layouts.",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Collections modules"] = {
description = "Modules containing functions used to implement collections (arrays, maps, etc.).",
parents = { "Utility modules", "Modules" },
}
raw_categories["Data modules"] = {
description = "Modules that do not contain functions, but only export a table of data that is used by other modules.",
additional = "Modules that are in this category should be imported using <code>mw.loadData</code> rather than <code>require</code>.",
parents = { "Modules" },
}
raw_categories["Character insertion data modules"] = {
preceding = "{{also|:Category:Character insertion templates}}",
description = "Modules containing data for use by {{temp|chars}}.",
parents = { "Data modules", "Character insertion modules" },
}
raw_categories["Dialect synonyms data modules"] = {
preceding = "{{also|:Category:Character insertion templates}}",
description = "Modules containing data for use by {{tl|dialect synonyms}}.",
parents = { "Data modules" },
}
raw_categories["Date modules"] = {
description = "Modules that implement functionality to convert or otherwise manipulate dates in various calendar systems.",
parents = { "Utility modules", "Modules" },
}
raw_categories["Debugging modules"] = {
description = "Modules used for debugging.",
additional = "Some should only be used in sandbox modules or when using the " ..
"[[mw:Extension:TemplateSandbox|{{MediaWiki:Templatesandbox-editform-legend}}]] button in the edit page of modules and templates.",
parents = { "Modules" },
}
raw_categories["Definition modules"] = {
preceding = "{{also|:Category:Definition templates}}",
description = "Modules that implement templates used in [[Wiktionary:Glossary#definition line|definition lines]] of entries.",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Deprecated modules"] = {
description = "Modules that should not be used, as their functions are performed by newer modules.",
parents = { "Modules", "Category:Wiktionary maintenance" },
}
raw_categories["Discussion modules"] = {
preceding = "{{also|:Category:Discussion templates}}",
description = "Modules concerning discussion pages.",
parents = { "Modules" },
}
raw_categories["Display text-generating modules"] = {
description = "Modules that are used to generate display text.",
additional = "Display text determines what is shown to the reader. In some languages it must be normalized, " ..
"due to common errors caused by confusable characters, or so as to ensure a consistent display format.",
parents = { "Modules" },
}
raw_categories["Documentation modules"] = {
preceding = "{{also|:Category:Documentation templates}}",
description = "Modules for generating documentation pages.",
parents = { "Modules" },
}
raw_categories["Encoding modules"] = {
description = "Modules for converting between different textual encodings.",
parents = { "Utility modules", "Modules" },
}
raw_categories["Entry-generating modules"] = {
preceding = "{{also|:Category:Entry templates}}",
description = "Modules with functions that are used to generate new entries.",
parents = { "Modules" },
}
raw_categories["Entry name-generating modules"] = {
description = "Modules that generate entry names, which typically have certain diacritics stripped compared with the form in links and headwords.",
parents = { "Modules" },
}
raw_categories["External link modules"] = {
preceding = "{{also|:Category:External link templates}}",
description = "Modules that are used in [[:Category:External link templates|external link templates]], i.e. which link to websites outside of the MediaWiki Foundation purview.",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Etymology modules"] = {
preceding = "{{also|:Category:Etymology templates}}",
description = "Modules that implement templates that define the etymology of entries.",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Form-of modules"] = {
preceding = "{{also|:Category:Form-of templates}}",
description = "Modules that generate the definition line of non-lemma forms, e.g. verb forms and noun forms.",
parents = { "Definition modules", "Page generation modules", "Modules" },
}
raw_categories["Headword-line modules"] = {
preceding = "{{also|:Category:Headword-line templates}}",
description = "Modules that support [[:Category:Headword-line templates by language|headword-line templates]] for a specific language.",
additional = "See also [[:Category:Headword-line templates]].",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Inflection modules"] = {
description = "Modules used to support [[:Category:Inflection-table templates by language|inflection templates]] for a specific language.",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Internal link modules"] = {
preceding = "{{also|:Category:Internal link templates}}",
description = "Modules that are used in [[:Category:Internal link templates|internal link templates]], i.e. which link between Wiktionary entries.",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Interwiki modules"] = {
preceding = "{{also|:Category:Interwiki templates}}",
description = "Modules that are used in [[:Category:Interwiki templates|interwiki templates]], i.e. which link to other MediaWiki projects.",
parents = { "Page generation modules", "Modules" },
}
raw_categories["JSON-generating modules"] = {
description = "Modules with functions that generate data in JSON format.",
parents = { "Modules" },
}
raw_categories["Language and script modules"] = {
description = "Modules that process language and script codes and return data on them.",
parents = { "Modules" },
}
raw_categories["List modules"] = {
preceding = "{{also|:Category:List templates}}",
description = "Modules that generate lists, tables or tree diagrams of entries or other structured data.",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Maintenance modules"] = {
preceding = "{{also|:Category:Maintenance templates}}",
description = "Modules that implement templates used for maintaining entries.",
additional = "Examples are cleanup templates (e.g. {{tl|attention}}), deletion templates (e.g. {{tl|rfd}}) and " ..
"verification templates (e.g. {{tl|rfv}}).",
parents = { "Modules" },
}
raw_categories["Number modules"] = {
preceding = "{{also|:Category:Number templates}}",
description = "Modules that handle conversion and/or formatting of numbers and numerals in various representations.",
parents = { "Utility modules", "Modules" },
}
raw_categories["Page generation modules"] = {
description = "Modules that generate parts of a mainspace page (e.g. headword line, definition, inflection, links, etc.).",
parents = { "Modules" },
}
raw_categories["Parameter parsing modules"] = {
description = "Modules containing functions used to parse template parameters.",
parents = { "Utility modules", "Modules" },
}
raw_categories["Pronunciation modules"] = {
preceding = "{{also|:Category:Pronunciation templates}}",
description = "Modules that implement templates used to create the language-specific pronunciation of entries.",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Pronunciation testcase modules"] = {
description = "Modules used to test other pronunciation modules.",
parents = { "Testcase modules", {name = "Pronunciation modules", sort = "Testcase"} },
}
raw_categories["Quotation and usage example modules"] = {
description = "Modules that implement templates used to format quotations and usage examples.",
parents = { "Definition modules", "Page generation modules", "Modules" },
}
raw_categories["Reference modules"] = {
preceding = "{{also|:Category:Reference templates}}",
description = "Modules that are used for [[:Category:Reference templates|reference templates]].",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Sandbox modules"] = {
description = "Test versions of modules intended for production use.",
parents = { "Modules" },
}
raw_categories["Semantic relation modules"] = {
preceding = "{{also|:Category:Semantic relation templates}}",
description = "Modules that implement templates used to indicate other terms semantically related to a " ..
"particular sense, e.g. [[synonym]]s or [[antonym]]s.",
parents = { "Page generation modules", "Modules" },
}
raw_categories["Sortkey-generating modules"] = {
description = "Modules that generate sortkeys, which determine the order of entry names in categories.",
parents = { "Modules" },
}
raw_categories["String modules"] = {
description = "Modules containing functions used to manipulate strings.",
parents = { "Utility modules", "Modules" },
}
raw_categories["Swadesh modules"] = {
description = "Modules containing [[Swadesh list]]s.",
parents = { "Modules" },
}
raw_categories["Template interface modules"] = {
description = "Modules whose purpose is to provide an interface between templates and the functions of a module.",
additional = "They are usually named <code>.../templates</code>, and the functions present within them usually all " ..
"have only a \"frame\" parameter.",
parents = { "Modules" },
}
raw_categories["Testcase modules"] = {
description = "Modules used to test other modules.",
parents = { "Modules" },
}
raw_categories["Failing testcase modules"] = {
description = "Modules which contain failures in their unit tests.",
additional = "This category is added automatically by [[Module:UnitTests]] when a test case fails.",
parents = { "Testcase modules" },
}
raw_categories["Tracking modules"] = {
description = "Modules that add tracking templates.",
parents = { "Debugging modules", "Modules" },
}
raw_categories["Transliteration modules"] = {
description = "Modules that automatically convert text in one script to another.",
additional = "Most of them convert non-Latin scripts to Latin (romanisation/romanization), and are used by " ..
"templates or modules to generate transliteration of text that is tagged with a particular language. Each " ..
"language's transliteration module is specified in its data table (for which, see the category {{catlink|Language data modules}}).",
parents = { "Modules" },
}
raw_categories["Transliteration testcase modules"] = {
description = "Modules used to test other transliteration modules.",
parents = { "Testcase modules", {name = "Transliteration modules", sort = "Testcase"} },
}
raw_categories["Unused modules"] = {
description = "Unused modules.",
parents = { "Modules" },
}
raw_categories["User sandbox modules"] = {
description = "Modules that are for personal use and testing by individual editors.",
additional = "These should all begin with <code>User:</code> followed by the user's name. If several " ..
"sandbox modules are needed by a single user, subpages can be created. These modules should not be used in real " ..
"Wiktionary content pages, as all content on those pages should be editable by anyone and, if necessary, edit protected.",
parents = { "Sandbox modules", "Modules" },
}
raw_categories["Utility modules"] = {
description = "Modules that serve some sort of utility purpose in various entries.",
additional = "Avoid categorizing directly into this category, but use one of the more specific (and semantically " ..
"well-defined) module categories. Note also that modules used by multiple languages should go directly in this " ..
"category if necessary, while modules only used by one language should be in [[:Category:Language-specific utility modules]].",
parents = { "Modules" },
}
raw_categories["Language-specific utility modules"] = {
description = "Modules that deal with several utilities needed by a certain language.",
additional = "Usually their names end with {{cd|-utilities}} or {{cd|-common}} (preceded by the language code), " ..
"although more specific utility modules that one language uses may reside here as well. If a utility is used by " ..
"many languages, it should be in [[:Category:Utility modules]].",
parents = {{name = "Utility modules", sort = " "}},
}
raw_categories["Vote modules"] = {
description = "Modules used to manage Wiktionary votes.",
parents = { "Modules" },
}
raw_categories["Wikitext parsing modules"] = {
description = "Modules that contain functions that grab the wikitext of a page and get information from it by " ..
"performing string operations on it.",
parents = { "Modules" },
}
-- Don't modify `raw_categories` while processing it, or items may be skipped.
local new_cats = {}
for raw_cat, obj in pairs(raw_categories) do
local by_script = raw_cat .. " by script"
if raw_cat ~= "Modules" and raw_cat ~= "Data modules" and not raw_categories[by_script] then
new_cats[by_script] = {
description = raw_cat .. ", categorized by the script they operate on or with.",
additional = raw_cat .. " are " .. mw.getContentLanguage():lcfirst(obj.description),
breadcrumb = "by script",
parents = {{name = raw_cat, sort = " "}},
}
end
end
for new_cat, obj in pairs(new_cats) do
raw_categories[new_cat] = obj
end
-----------------------------------------------------------------------------
-- --
-- RAW HANDLERS --
-- --
-----------------------------------------------------------------------------
for _, mod_type in ipairs {"Entry name-generating", "Sortkey-generating", "Transliteration"} do
insert(raw_handlers, function(data)
local n, suffix = data.category:match(("^%s modules used by (%%d+) language(s?)$"):format(pattern_escape(mod_type)))
-- Only match if there are no leading zeroes and the suffix is correct.
if not (n and not n:match("^0%d") and suffix == (n == "1" and "" or "s")) then
return
end
return {
breadcrumb = ("used by %d language%s"):format(n, suffix),
description = data.category .. ".",
can_be_empty = true,
parents = {
{name = ("%s modules"):format(mod_type), sort = require("Module:category tree").numeral_sortkey(n)},
},
}
end)
end
-- Add breadcrumb by chopping off the parent (or the parent's parent, etc.) from the end of the label, if possible.
for key, data in pairs(raw_categories) do
if not data.breadcrumb then
local parent = data.parents[1]
while true do
if type(parent) == "string" then
local parent_re = " " .. pattern_escape(mw.getContentLanguage():lcfirst(parent)) .. "$"
if key:find(parent_re) then
data.breadcrumb = key:gsub(parent_re, "")
break
end
if raw_categories[parent] then
parent = raw_categories[parent].parents[1]
else
break
end
else
break
end
end
end
end
return {LABELS = labels, RAW_CATEGORIES = raw_categories, RAW_HANDLERS = raw_handlers}
jdbdyi3avh90j0o1aed4c31lxqcdoul
مۆدیوول:pages
828
10674
36913
34456
2026-08-17T20:28:35Z
Ghybu
12
36913
Scribunto
text/plain
local export = {}
local string_utilities_module = "Module:string utilities"
local concat = table.concat
local find = string.find
local format = string.format
local getmetatable = getmetatable
local get_current_section -- defined below
local get_namespace_shortcut -- defined below
local get_pagetype -- defined below
local gsub = string.gsub
local insert = table.insert
local is_internal_title -- defined below
local is_title -- defined below
local lower = string.lower
local match = string.match
local new_title = mw.title.new
local require = require
local sub = string.sub
local title_equals = mw.title.equals
local tonumber = tonumber
local type = type
local ufind = mw.ustring.find
local unstrip_nowiki = mw.text.unstripNoWiki
--[==[
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==]
local function decode_entities(...)
decode_entities = require(string_utilities_module).decode_entities
return decode_entities(...)
end
local function ulower(...)
ulower = require(string_utilities_module).lower
return ulower(...)
end
local function trim(...)
trim = require(string_utilities_module).trim
return trim(...)
end
--[==[
Loaders for objects, which load data (or some other object) into some variable, which can then be accessed as "foo or get_foo()", where the function get_foo sets the object to "foo" and then returns it. This ensures they are only loaded when needed, and avoids the need to check for the existence of the object each time, since once "foo" has been set, "get_foo" will not be called again.]==]
local current_frame
local function get_current_frame()
current_frame, get_current_frame = mw.getCurrentFrame(), nil
return current_frame
end
local parent_frame
local function get_parent_frame()
parent_frame, get_parent_frame = (current_frame or get_current_frame()):getParent(), nil
return parent_frame
end
local namespace_shortcuts
local function get_namespace_shortcuts()
namespace_shortcuts, get_namespace_shortcuts = {
[4] = "WT",
[10] = "T",
[14] = "CAT",
[100] = "AP",
[110] = "WS",
[118] = "RC",
[828] = "MOD",
}, nil
return namespace_shortcuts
end
do
local transcluded
--[==[
Returns {true} if the current {{tl|#invoke:}} is being transcluded, or {false} if not. If the current {{tl|#invoke:}} is part of a template, for instance, this template will therefore return {true}.
Note that if a template containing an {{tl|#invoke:}} is used on its own page (e.g. to display a demonstration), this function is still able to detect that this is transclusion. This is an improvement over the other method for detecting transclusion, which is to check the parent frame title against the current page title, which fails to detect transclusion in that instance.]==]
function export.is_transcluded()
if transcluded == nil then
transcluded = (parent_frame or get_parent_frame()) and parent_frame:preprocess("<includeonly>1</includeonly>") == "1" or false
end
return transcluded
end
end
do
local preview
--[==[
Returns {true} if the page is currently being viewed in preview, or {false} if not.]==]
function export.is_preview()
if preview == nil then
preview = (current_frame or get_current_frame()):preprocess("{{REVISIONID}}") == ""
end
return preview
end
end
--[==[
Returns {true} if the input is a title object, or {false} if not. This therefore '''includes''' external title objects (i.e. those for pages on other wikis), such as [[w:Example]], unlike `is_internal_title` below.]==]
function export.is_title(val)
if not (val and type(val) == "table") then
return false
end
local mt = getmetatable(val)
-- There's no foolproof method for checking for a title object, but the
-- __eq metamethod should be mw.title.equals unless the object has been
-- seriously messed around with.
return mt and
type(mt) == "table" and
getmetatable(mt) == nil and
mt.__eq == title_equals and
true or false
end
is_title = export.is_title
--[==[
Returns {true} if the input is an internal title object, or {false} if not. An internal title object is a title object for a page on this wiki, such as [[example]]. This therefore '''excludes''' external title objects (i.e. those for pages on other wikis), such as [[w:Example]], unlike `is_title` above.]==]
function export.is_internal_title(title)
-- Note: Mainspace titles starting with "#" should be invalid, but a bug in mw.title.new and mw.title.makeTitle means a title object is returned that has the empty string for prefixedText, so they need to be filtered out.
return is_title(title) and #title.prefixedText > 0 and #title.interwiki == 0
end
is_internal_title = export.is_internal_title
--[==[
Returns {true} if the input string is a valid link target, or {false} if not. This therefore '''includes''' link targets to other wikis, such as [[w:Example]], unlike `is_valid_page_name` below.]==]
function export.is_valid_link_target(target)
local target_type = type(target)
if target_type == "string" then
return is_title(new_title(target))
end
error(format("bad argument #1 to 'is_valid_link_target' (string expected, got %s)", target_type), 2)
end
--[==[
Returns {true} if the input string is a valid page name on this wiki, or {false} if not. This therefore '''excludes''' page names on other wikis, such as [[w:Example]], unlike `is_valid_link_target` above.]==]
function export.is_valid_page_name(name)
local name_type = type(name)
if name_type == "string" then
return is_internal_title(new_title(name))
end
error(format("bad argument #1 to 'is_valid_page_name' (string expected, got %s)", name_type), 2)
end
--[==[
Given a title object, returns a full link target which will always unambiguously link to it.
For instance, the input {"foo"} (for the page [[foo]]) returns {":foo"}, as a leading colon always refers to mainspace, even when other namespaces might be assumed (e.g. when transcluding using `{{ }}` syntax).
If `shortcut` is set, then the returned target will use the namespace shortcut, if any; for example, the title for `Template:foo` would return {"T:foo"} instead of {"Template:foo"}.]==]
function export.get_link_target(title, shortcut)
if not is_title(title) then
error(format("bad argument #1 to 'is_valid_link_target' (title object expected, got %s)", type(title)))
elseif title.interwiki ~= "" then
return title.fullText
elseif shortcut then
local fragment = title.fragment
if fragment == "" then
return get_namespace_shortcut(title) .. ":" .. title.text
end
return get_namespace_shortcut(title) .. ":" .. title.text .. "#" .. fragment
elseif title.namespace == 0 then
return ":" .. title.fullText
end
return title.fullText
end
do
local function find_sandbox(text)
return find(text, "^User:.") or find(lower(text), "sandbox", 1, true)
end
local function get_transclusion_subtypes(title, main_type, documentation, page_suffix)
local text, subtypes = title.text, {main_type}
-- Any template/module with "sandbox" in the title. These are impossible
-- to screen for more accurately, as there's no consistent pattern. Also
-- any user sandboxes in the form (e.g.) "Template:User:...".
local sandbox = find_sandbox(text)
if sandbox then
insert(subtypes, "sandbox")
end
-- Any template/module testcases (which can be labelled and/or followed
-- by further subpages).
local testcase = find(text, "./[Tt]estcases?%f[%L]")
if testcase then
-- Order "testcase" and "sandbox" based on where the patterns occur
-- in the title.
local n = sandbox and sandbox < testcase and 3 or 2
insert(subtypes, n, "testcase")
end
-- Any template/module documentation pages.
if documentation then
insert(subtypes, "documentation")
end
local final = subtypes[#subtypes]
if not (final == main_type and not page_suffix or final == "sandbox") then
insert(subtypes, "page")
end
return concat(subtypes, " ")
end
local function get_snippet_subtypes(title, main_type, documentation)
local ns = title.namespace
return get_transclusion_subtypes(title, (
ns == 2 and "user " or
ns == 8 and match(title.text, "^Gadget-.") and "gadget " or
""
) .. main_type, documentation)
end
--[==[
Returns the page type of the input title object in a format which can be used in running text.]==]
function export.get_pagetype(title)
if not is_internal_title(title) then
error(mw.dumpObject(title.fullText) .. " is not a valid page name.")
end
-- If possibly a documentation page, get the base title and set the
-- `documentation` flag.
local content_model, text, documentation = title.contentModel
if content_model == "wikitext" then
text = title.text
if title.isSubpage and title.subpageText == "documentation" then
local base_title = title.basePageTitle
if base_title then
title, content_model, text, documentation = base_title, base_title.contentModel, base_title.text, true
end
end
end
-- Content models have overriding priority, as they can appear in
-- nonstandard places due to page content model changes.
if content_model == "css" or content_model == "sanitized-css" then
return get_snippet_subtypes(title, "stylesheet", documentation)
elseif content_model == "javascript" then
return get_snippet_subtypes(title, "script", documentation)
elseif content_model == "json" then
return get_snippet_subtypes(title, "JSON data", documentation)
elseif content_model == "MassMessageListContent" then
return get_snippet_subtypes(title, "mass message delivery list", documentation)
-- Modules.
elseif content_model == "Scribunto" then
return get_transclusion_subtypes(title, "module", documentation, false)
elseif content_model == "text" then
return "page" -- ???
-- Otherwise, the content model is "wikitext", so check namespaces.
elseif title.isTalkPage then
return "talk page"
end
local ns = title.namespace
-- Main namespace.
if ns == 0 then
return "entry"
-- Wiktionary:
elseif ns == 4 then
return find_sandbox(title.text) and "sandbox" or "project page"
-- Template:
elseif ns == 10 then
return get_transclusion_subtypes(title, "template", documentation, false)
end
-- Convert the namespace to lowercase, unless it contains a capital
-- letter after the initial letter (e.g. MediaWiki, TimedText). Also
-- normalize any underscores.
local ns_text = gsub(title.nsText, "_", " ")
if ufind(ns_text, "^%U*$", 2) then
ns_text = ulower(ns_text)
end
-- User:
if ns == 2 then
return ns_text .. " " .. (title.isSubpage and "subpage" or "page")
-- Category: and Appendix:
elseif ns == 14 or ns == 100 then
return ns_text
-- Thesaurus: and Reconstruction:
elseif ns == 110 or ns == 118 then
return ns_text .. " entry"
end
return ns_text .. " page"
end
get_pagetype = export.get_pagetype
end
--[==[
Returns {true} if the input title object is for a content page, or {false} if not. A content page is a page that is considered part of the dictionary itself, and excludes pages for discussion, administration, maintenance etc.]==]
function export.is_content_page(title)
if not is_internal_title(title) then
error(mw.dumpObject(title.fullText) .. " is not a valid page name.")
end
local ns = title.namespace
-- (main), Appendix, Thesaurus, Citations, Reconstruction.
return (ns == 0 or ns == 100 or ns == 110 or ns == 114 or ns == 118) and
title.contentModel == "wikitext"
end
--[==[
Returns {true} if the input title object is for a documentation page, or {false} if not.]==]
function export.is_documentation(title)
return match(get_pagetype(title), "%f[%w]documentation%f[%W]") and true or false
end
--[==[
Returns {true} if the input title object is for a sandbox, or {false} if not.
By default, sandbox documentation pages are excluded, but this can be overridden with the `include_documentation` parameter.]==]
function export.is_sandbox(title, include_documentation)
local pagetype = get_pagetype(title)
return match(pagetype, "%f[%w]sandbox%f[%W]") and (
include_documentation or
not match(pagetype, "%f[%w]documentation%f[%W]")
) and true or false
end
--[==[
Returns {true} if the input title object is for a testcase page, or {false} if not.
By default, testcase documentation pages are excluded, but this can be overridden with the `include_documentation` parameter.]==]
function export.is_testcase_page(title, include_documentation)
local pagetype = get_pagetype(title)
return match(pagetype, "%f[%w]testcase%f[%W]") and (
include_documentation or
not match(pagetype, "%f[%w]documentation%f[%W]")
) and true or false
end
--[==[
Returns the namespace shortcut for the input title object, or else the namespace text. For example, a `Template:` title returns {"T"}, a `Module:` title returns {"MOD"}, and a `User:` title returns {"User"}.]==]
function export.get_namespace_shortcut(title)
return (namespace_shortcuts or get_namespace_shortcuts())[title.namespace] or title.nsText
end
get_namespace_shortcut = export.get_namespace_shortcut
do
local function check_level(lvl)
if type(lvl) ~= "number" then
error("Heading levels must be numbers.")
elseif lvl < 1 or lvl > 6 or lvl % 1 ~= 0 then
error("Heading levels must be integers between 1 and 6.")
end
return lvl
end
--[==[
A helper function which iterates over the headings in `text`, which should be the content of a page or (main) section.
Each iteration returns three values: `sec` (the section title), `lvl` (the section level) and `loc` (the index of the section in the given text, from the first equals sign). The section title will be automatically trimmed, and any HTML entities will be resolved.
The optional parameter `a` (which should be an integer between 1 and 6) can be used to ensure that only headings of the specified level are iterated over. If `b` is also given, then they are treated as a range.
The optional parameters `a` and `b` can be used to specify a range, so that only headings with levels in that range are returned.]==]
local function find_headings(text, a, b)
a = a and check_level(a) or nil
b = b and check_level(b) or a or nil
local start, loc, lvl, sec = 1
return function()
repeat
loc, lvl, sec, start = match(text, "()%f[^%z\n](==?=?=?=?=?)([^\n]+)%2[\t ]*%f[%z\n]()", start)
lvl = lvl and #lvl
until not (sec and a) or (lvl >= a and lvl <= b)
return sec and trim(decode_entities(sec)) or nil, lvl, loc
end
end
local function _get_section(content, name, level)
if not (content and name) then
return nil
elseif find(name, "\n", 1, true) then
error("Heading name cannot contain a newline.")
end
level = level and check_level(level) or nil
name = trim(decode_entities(name))
local start
for sec, lvl, loc in find_headings(content, level and 1 or nil, level) do
if start and lvl <= level then
return sub(content, start, loc - 1)
elseif not start and (not level or lvl == level) and sec == name then
start, level = loc, lvl
end
end
return start and sub(content, start)
end
--[==[
A helper function to return the content of a page section.
`content` is raw wikitext, `name` is the requested section, and `level` is an optional parameter that specifies
the required section heading level. If `level` is not supplied, then the first section called `name` is returned.
`name` can either be a string or table of section names. If a table, each name represents a section that has the
next as a subsection. For example, { {"Spanish", "Noun"}} will return the first matching section called "Noun"
under a section called "Spanish". These do not have to be at adjacent levels ("Noun" might be L4, while "Spanish"
is L2). If `level` is given, it refers to the last name in the table (i.e. the name of the section to be returned).
The returned section includes all of its subsections. If no matching section is found, return {nil}.]==]
function export.get_section(content, names, level)
if type(names) ~= "table" then
return _get_section(content, names, level)
end
local i = 1
local name = names[i]
if not name then
error("Must specify at least 1 section.")
end
while true do
local nxt_i = i + 1
local nxt = names[nxt_i]
if nxt == nil then
return _get_section(content, name, level)
end
content = _get_section(content, name)
if content == nil then
return nil
elseif i == 6 then
error("Not possible specify more than 6 sections: headings only go up to level 6.")
end
i = nxt_i
name = names[i]
end
return content
end
end
do
local current_section
--[==[
A function which returns the number of the page section which contains the current {#invoke}, or {0} if the section can't be determined.]==]
function export.get_current_section()
if current_section ~= nil then
return current_section
end
local frame = parent_frame or get_parent_frame()
while frame do
if find(frame:getTitle(), "^Module:") then
current_section = 0
return 0
end
frame = frame:getParent()
end
local extension_tag = (current_frame or get_current_frame()).extensionTag
-- We determine the section via the heading strip marker count, since they're numbered sequentially, but the only way to do this is to generate a fake heading via frame:preprocess(). The native parser assigns each heading a unique marker, but frame:preprocess() will return copies of older markers if the heading is identical to one further up the page, so the fake heading has to be unique to the page. The best way to do this is to feed it a heading containing a nowiki marker (which we will need later), since those are always unique.
local nowiki_marker = extension_tag(current_frame, "nowiki")
-- Note: heading strip markers have a different syntax to the ones used for tags.
local h = tonumber(match(
current_frame:preprocess("=" .. nowiki_marker .. "="),
"\127'\"`UNIQ%-%-h%-(%d+)%-%-QINU`\"'\127"
))
-- For some reason, [[Special:ExpandTemplates]] doesn't generate a heading strip marker, so if that happens we simply abort early.
if not h then
return 0
end
-- The only way to get the section number is to increment the heading count, so we store the offset in nowiki strip markers which can be retrieved by procedurally unstripping nowiki markers, counting backwards until we find a match.
local n, offset = tonumber(match(
nowiki_marker,
"\127'\"`UNIQ%-%-nowiki%-([%dA-F]+)%-QINU`\"'\127"
), 16)
while not offset and n > 0 do
n = n - 1
offset = match(
unstrip_nowiki(format("\127'\"`UNIQ--nowiki-%08X-QINU`\"'\127", n)),
"^HEADING\1(%d+)" -- Prefix "HEADING\1" prevents collisions.
)
end
offset = offset and (offset + 1) or 0
extension_tag(current_frame, "nowiki", "HEADING\1" .. offset)
current_section = h - offset
return current_section
end
get_current_section = export.get_current_section
end
do
local L2_sections, current_L2
local function get_L2_sections()
L2_sections, get_L2_sections = mw.loadData("Module:headword/data").page.L2_sections, nil
return L2_sections
end
--[==[
A function which returns the name of the L2 language section which contains the current {#invoke}.]==]
function export.get_current_L2()
if current_L2 ~= nil then
return current_L2 or nil -- Return nil if current_L2 is false (i.e. there's no L2).
end
local section = get_current_section()
while section > 0 do
local L2 = (L2_sections or get_L2_sections())[section]
if L2 then
current_L2 = L2
return L2
end
section = section - 1
end
current_L2 = false
return nil
end
end
return export
gdpkp4jhb7nfkcr0r3uwx8kn3hzfj9h
36930
36913
2026-08-17T23:47:30Z
Ghybu
12
"export.get current section()" failed to find the sections. It has been modified for the Sorani wiki to enable their detection.
36930
Scribunto
text/plain
local export = {}
local string_utilities_module = "Module:string utilities"
local concat = table.concat
local find = string.find
local format = string.format
local getmetatable = getmetatable
local get_current_section -- defined below
local get_namespace_shortcut -- defined below
local get_pagetype -- defined below
local gsub = string.gsub
local insert = table.insert
local is_internal_title -- defined below
local is_title -- defined below
local lower = string.lower
local match = string.match
local new_title = mw.title.new
local require = require
local sub = string.sub
local title_equals = mw.title.equals
local tonumber = tonumber
local type = type
local ufind = mw.ustring.find
local unstrip_nowiki = mw.text.unstripNoWiki
--[==[
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==]
local function decode_entities(...)
decode_entities = require(string_utilities_module).decode_entities
return decode_entities(...)
end
local function ulower(...)
ulower = require(string_utilities_module).lower
return ulower(...)
end
local function trim(...)
trim = require(string_utilities_module).trim
return trim(...)
end
--[==[
Loaders for objects, which load data (or some other object) into some variable, which can then be accessed as "foo or get_foo()", where the function get_foo sets the object to "foo" and then returns it. This ensures they are only loaded when needed, and avoids the need to check for the existence of the object each time, since once "foo" has been set, "get_foo" will not be called again.]==]
local current_frame
local function get_current_frame()
current_frame, get_current_frame = mw.getCurrentFrame(), nil
return current_frame
end
local parent_frame
local function get_parent_frame()
parent_frame, get_parent_frame = (current_frame or get_current_frame()):getParent(), nil
return parent_frame
end
local namespace_shortcuts
local function get_namespace_shortcuts()
namespace_shortcuts, get_namespace_shortcuts = {
[4] = "WT",
[10] = "T",
[14] = "CAT",
[100] = "AP",
[110] = "WS",
[118] = "RC",
[828] = "MOD",
}, nil
return namespace_shortcuts
end
do
local transcluded
--[==[
Returns {true} if the current {{tl|#invoke:}} is being transcluded, or {false} if not. If the current {{tl|#invoke:}} is part of a template, for instance, this template will therefore return {true}.
Note that if a template containing an {{tl|#invoke:}} is used on its own page (e.g. to display a demonstration), this function is still able to detect that this is transclusion. This is an improvement over the other method for detecting transclusion, which is to check the parent frame title against the current page title, which fails to detect transclusion in that instance.]==]
function export.is_transcluded()
if transcluded == nil then
transcluded = (parent_frame or get_parent_frame()) and parent_frame:preprocess("<includeonly>1</includeonly>") == "1" or false
end
return transcluded
end
end
do
local preview
--[==[
Returns {true} if the page is currently being viewed in preview, or {false} if not.]==]
function export.is_preview()
if preview == nil then
preview = (current_frame or get_current_frame()):preprocess("{{REVISIONID}}") == ""
end
return preview
end
end
--[==[
Returns {true} if the input is a title object, or {false} if not. This therefore '''includes''' external title objects (i.e. those for pages on other wikis), such as [[w:Example]], unlike `is_internal_title` below.]==]
function export.is_title(val)
if not (val and type(val) == "table") then
return false
end
local mt = getmetatable(val)
-- There's no foolproof method for checking for a title object, but the
-- __eq metamethod should be mw.title.equals unless the object has been
-- seriously messed around with.
return mt and
type(mt) == "table" and
getmetatable(mt) == nil and
mt.__eq == title_equals and
true or false
end
is_title = export.is_title
--[==[
Returns {true} if the input is an internal title object, or {false} if not. An internal title object is a title object for a page on this wiki, such as [[example]]. This therefore '''excludes''' external title objects (i.e. those for pages on other wikis), such as [[w:Example]], unlike `is_title` above.]==]
function export.is_internal_title(title)
-- Note: Mainspace titles starting with "#" should be invalid, but a bug in mw.title.new and mw.title.makeTitle means a title object is returned that has the empty string for prefixedText, so they need to be filtered out.
return is_title(title) and #title.prefixedText > 0 and #title.interwiki == 0
end
is_internal_title = export.is_internal_title
--[==[
Returns {true} if the input string is a valid link target, or {false} if not. This therefore '''includes''' link targets to other wikis, such as [[w:Example]], unlike `is_valid_page_name` below.]==]
function export.is_valid_link_target(target)
local target_type = type(target)
if target_type == "string" then
return is_title(new_title(target))
end
error(format("bad argument #1 to 'is_valid_link_target' (string expected, got %s)", target_type), 2)
end
--[==[
Returns {true} if the input string is a valid page name on this wiki, or {false} if not. This therefore '''excludes''' page names on other wikis, such as [[w:Example]], unlike `is_valid_link_target` above.]==]
function export.is_valid_page_name(name)
local name_type = type(name)
if name_type == "string" then
return is_internal_title(new_title(name))
end
error(format("bad argument #1 to 'is_valid_page_name' (string expected, got %s)", name_type), 2)
end
--[==[
Given a title object, returns a full link target which will always unambiguously link to it.
For instance, the input {"foo"} (for the page [[foo]]) returns {":foo"}, as a leading colon always refers to mainspace, even when other namespaces might be assumed (e.g. when transcluding using `{{ }}` syntax).
If `shortcut` is set, then the returned target will use the namespace shortcut, if any; for example, the title for `Template:foo` would return {"T:foo"} instead of {"Template:foo"}.]==]
function export.get_link_target(title, shortcut)
if not is_title(title) then
error(format("bad argument #1 to 'is_valid_link_target' (title object expected, got %s)", type(title)))
elseif title.interwiki ~= "" then
return title.fullText
elseif shortcut then
local fragment = title.fragment
if fragment == "" then
return get_namespace_shortcut(title) .. ":" .. title.text
end
return get_namespace_shortcut(title) .. ":" .. title.text .. "#" .. fragment
elseif title.namespace == 0 then
return ":" .. title.fullText
end
return title.fullText
end
do
local function find_sandbox(text)
return find(text, "^User:.") or find(lower(text), "sandbox", 1, true)
end
local function get_transclusion_subtypes(title, main_type, documentation, page_suffix)
local text, subtypes = title.text, {main_type}
-- Any template/module with "sandbox" in the title. These are impossible
-- to screen for more accurately, as there's no consistent pattern. Also
-- any user sandboxes in the form (e.g.) "Template:User:...".
local sandbox = find_sandbox(text)
if sandbox then
insert(subtypes, "sandbox")
end
-- Any template/module testcases (which can be labelled and/or followed
-- by further subpages).
local testcase = find(text, "./[Tt]estcases?%f[%L]")
if testcase then
-- Order "testcase" and "sandbox" based on where the patterns occur
-- in the title.
local n = sandbox and sandbox < testcase and 3 or 2
insert(subtypes, n, "testcase")
end
-- Any template/module documentation pages.
if documentation then
insert(subtypes, "documentation")
end
local final = subtypes[#subtypes]
if not (final == main_type and not page_suffix or final == "sandbox") then
insert(subtypes, "page")
end
return concat(subtypes, " ")
end
local function get_snippet_subtypes(title, main_type, documentation)
local ns = title.namespace
return get_transclusion_subtypes(title, (
ns == 2 and "user " or
ns == 8 and match(title.text, "^Gadget-.") and "gadget " or
""
) .. main_type, documentation)
end
--[==[
Returns the page type of the input title object in a format which can be used in running text.]==]
function export.get_pagetype(title)
if not is_internal_title(title) then
error(mw.dumpObject(title.fullText) .. " is not a valid page name.")
end
-- If possibly a documentation page, get the base title and set the
-- `documentation` flag.
local content_model, text, documentation = title.contentModel
if content_model == "wikitext" then
text = title.text
if title.isSubpage and title.subpageText == "documentation" then
local base_title = title.basePageTitle
if base_title then
title, content_model, text, documentation = base_title, base_title.contentModel, base_title.text, true
end
end
end
-- Content models have overriding priority, as they can appear in
-- nonstandard places due to page content model changes.
if content_model == "css" or content_model == "sanitized-css" then
return get_snippet_subtypes(title, "stylesheet", documentation)
elseif content_model == "javascript" then
return get_snippet_subtypes(title, "script", documentation)
elseif content_model == "json" then
return get_snippet_subtypes(title, "JSON data", documentation)
elseif content_model == "MassMessageListContent" then
return get_snippet_subtypes(title, "mass message delivery list", documentation)
-- Modules.
elseif content_model == "Scribunto" then
return get_transclusion_subtypes(title, "module", documentation, false)
elseif content_model == "text" then
return "page" -- ???
-- Otherwise, the content model is "wikitext", so check namespaces.
elseif title.isTalkPage then
return "talk page"
end
local ns = title.namespace
-- Main namespace.
if ns == 0 then
return "entry"
-- Wiktionary:
elseif ns == 4 then
return find_sandbox(title.text) and "sandbox" or "project page"
-- Template:
elseif ns == 10 then
return get_transclusion_subtypes(title, "template", documentation, false)
end
-- Convert the namespace to lowercase, unless it contains a capital
-- letter after the initial letter (e.g. MediaWiki, TimedText). Also
-- normalize any underscores.
local ns_text = gsub(title.nsText, "_", " ")
if ufind(ns_text, "^%U*$", 2) then
ns_text = ulower(ns_text)
end
-- User:
if ns == 2 then
return ns_text .. " " .. (title.isSubpage and "subpage" or "page")
-- Category: and Appendix:
elseif ns == 14 or ns == 100 then
return ns_text
-- Thesaurus: and Reconstruction:
elseif ns == 110 or ns == 118 then
return ns_text .. " entry"
end
return ns_text .. " page"
end
get_pagetype = export.get_pagetype
end
--[==[
Returns {true} if the input title object is for a content page, or {false} if not. A content page is a page that is considered part of the dictionary itself, and excludes pages for discussion, administration, maintenance etc.]==]
function export.is_content_page(title)
if not is_internal_title(title) then
error(mw.dumpObject(title.fullText) .. " is not a valid page name.")
end
local ns = title.namespace
-- (main), Appendix, Thesaurus, Citations, Reconstruction.
return (ns == 0 or ns == 100 or ns == 110 or ns == 114 or ns == 118) and
title.contentModel == "wikitext"
end
--[==[
Returns {true} if the input title object is for a documentation page, or {false} if not.]==]
function export.is_documentation(title)
return match(get_pagetype(title), "%f[%w]documentation%f[%W]") and true or false
end
--[==[
Returns {true} if the input title object is for a sandbox, or {false} if not.
By default, sandbox documentation pages are excluded, but this can be overridden with the `include_documentation` parameter.]==]
function export.is_sandbox(title, include_documentation)
local pagetype = get_pagetype(title)
return match(pagetype, "%f[%w]sandbox%f[%W]") and (
include_documentation or
not match(pagetype, "%f[%w]documentation%f[%W]")
) and true or false
end
--[==[
Returns {true} if the input title object is for a testcase page, or {false} if not.
By default, testcase documentation pages are excluded, but this can be overridden with the `include_documentation` parameter.]==]
function export.is_testcase_page(title, include_documentation)
local pagetype = get_pagetype(title)
return match(pagetype, "%f[%w]testcase%f[%W]") and (
include_documentation or
not match(pagetype, "%f[%w]documentation%f[%W]")
) and true or false
end
--[==[
Returns the namespace shortcut for the input title object, or else the namespace text. For example, a `Template:` title returns {"T"}, a `Module:` title returns {"MOD"}, and a `User:` title returns {"User"}.]==]
function export.get_namespace_shortcut(title)
return (namespace_shortcuts or get_namespace_shortcuts())[title.namespace] or title.nsText
end
get_namespace_shortcut = export.get_namespace_shortcut
do
local function check_level(lvl)
if type(lvl) ~= "number" then
error("Heading levels must be numbers.")
elseif lvl < 1 or lvl > 6 or lvl % 1 ~= 0 then
error("Heading levels must be integers between 1 and 6.")
end
return lvl
end
--[==[
A helper function which iterates over the headings in `text`, which should be the content of a page or (main) section.
Each iteration returns three values: `sec` (the section title), `lvl` (the section level) and `loc` (the index of the section in the given text, from the first equals sign). The section title will be automatically trimmed, and any HTML entities will be resolved.
The optional parameter `a` (which should be an integer between 1 and 6) can be used to ensure that only headings of the specified level are iterated over. If `b` is also given, then they are treated as a range.
The optional parameters `a` and `b` can be used to specify a range, so that only headings with levels in that range are returned.]==]
local function find_headings(text, a, b)
a = a and check_level(a) or nil
b = b and check_level(b) or a or nil
local start, loc, lvl, sec = 1
return function()
repeat
loc, lvl, sec, start = match(text, "()%f[^%z\n](==?=?=?=?=?)([^\n]+)%2[\t ]*%f[%z\n]()", start)
lvl = lvl and #lvl
until not (sec and a) or (lvl >= a and lvl <= b)
return sec and trim(decode_entities(sec)) or nil, lvl, loc
end
end
local function _get_section(content, name, level)
if not (content and name) then
return nil
elseif find(name, "\n", 1, true) then
error("Heading name cannot contain a newline.")
end
level = level and check_level(level) or nil
name = trim(decode_entities(name))
local start
for sec, lvl, loc in find_headings(content, level and 1 or nil, level) do
if start and lvl <= level then
return sub(content, start, loc - 1)
elseif not start and (not level or lvl == level) and sec == name then
start, level = loc, lvl
end
end
return start and sub(content, start)
end
--[==[
A helper function to return the content of a page section.
`content` is raw wikitext, `name` is the requested section, and `level` is an optional parameter that specifies
the required section heading level. If `level` is not supplied, then the first section called `name` is returned.
`name` can either be a string or table of section names. If a table, each name represents a section that has the
next as a subsection. For example, { {"Spanish", "Noun"}} will return the first matching section called "Noun"
under a section called "Spanish". These do not have to be at adjacent levels ("Noun" might be L4, while "Spanish"
is L2). If `level` is given, it refers to the last name in the table (i.e. the name of the section to be returned).
The returned section includes all of its subsections. If no matching section is found, return {nil}.]==]
function export.get_section(content, names, level)
if type(names) ~= "table" then
return _get_section(content, names, level)
end
local i = 1
local name = names[i]
if not name then
error("Must specify at least 1 section.")
end
while true do
local nxt_i = i + 1
local nxt = names[nxt_i]
if nxt == nil then
return _get_section(content, name, level)
end
content = _get_section(content, name)
if content == nil then
return nil
elseif i == 6 then
error("Not possible specify more than 6 sections: headings only go up to level 6.")
end
i = nxt_i
name = names[i]
end
return content
end
end
do
local current_section
--[==[
A function which returns the number of the page section which contains the current {#invoke}, or {0} if the section can't be determined.]==]
function export.get_current_section()
if current_section ~= nil then
return current_section
end
local frame = parent_frame or get_parent_frame()
while frame do
if find(frame:getTitle(), "^Module:") then
current_section = 0
return 0
end
frame = frame:getParent()
end
local current = current_frame or get_current_frame()
local extension_tag = current.extensionTag
-- CKB: an empty nowiki does not produce a marker.
-- Therefore, we give it some content.
local nowiki_marker = extension_tag(
current,
"nowiki",
"CKBSEC"
)
-- Generate an artificial heading and retrieve its number.
local h = tonumber(match(
current:preprocess("=" .. nowiki_marker .. "="),
"\127'\"`UNIQ%-%-h%-(%d+)%-%-QINU`\"'\127"
))
if not h then
current_section = 0
return 0
end
-- Retrieve the number of the nowiki marker.
local n, offset = tonumber(match(
nowiki_marker,
"\127'\"`UNIQ%-%-nowiki%-([%dA-F]+)%-QINU`\"'\127"
), 16)
-- Search for the offset in previous markers.
while not offset and n > 0 do
n = n - 1
offset = match(
unstrip_nowiki(
format(
"\127'\"`UNIQ--nowiki-%08X-QINU`\"'\127",
n
)
),
"^CKBSEC\1(%d+)"
)
end
offset = offset and tonumber(offset) or 0
-- Store the offset.
extension_tag(
current,
"nowiki",
"CKBSEC\1" .. offset
)
-- On ckb, the first generated heading is h = 0.
-- MediaWiki sections start at 1.
current_section = h - offset + 1
return current_section
end
get_current_section = export.get_current_section
end
do
local L2_sections, current_L2
local function get_L2_sections()
L2_sections, get_L2_sections = mw.loadData("Module:headword/data").page.L2_sections, nil
return L2_sections
end
--[==[
A function which returns the name of the L2 language section which contains the current {#invoke}.]==]
function export.get_current_L2()
if current_L2 ~= nil then
return current_L2 or nil -- Return nil if current_L2 is false (i.e. there's no L2).
end
local section = get_current_section()
while section > 0 do
local L2 = (L2_sections or get_L2_sections())[section]
if L2 then
current_L2 = L2
return L2
end
section = section - 1
end
current_L2 = false
return nil
end
end
return export
k4p2ffbzn0qobygq5x7ic24qc83h777
automatic
0
11054
36951
35174
2026-08-18T03:41:10Z
Ghybu
12
/* ئینگلیزی */
36951
wikitext
text/x-wiki
== ئینگلیزی ==
===وشەڕەتناسی ===
{{واڵا}}
===گۆکردن===
* {{IPA|en|/ˌɔː.təˈmæt.ɪk/|a=UK}}
* {{IPA|en|/ˌɔː.təˈmæt.ɪk/|[ˌɔː.ɾəˈmæɾ.ɪk]|a=US}}
** {{IPA|en|/ˌɑː.təˈmæt.ɪk/|[ˌɑː.ɾəˈmæɾ.ɪk]|a=cot-caught}}
*** {{audio|en|en-us-automatic.ogg|a=California}}
==== ھاوەڵناو ====
{{en-adj}}
# شتێک کە بۆ خۆی کاردەکات و پێویستی بە کۆنترۆڵکردن لەلایەن [[مرۆڤ|مرۆڤەوە]] نییە
#: {{ux|en|The automatic pilot [[system]] on the [[airplane]] kept it on [[course]] even during [[turbulence]].|سیستەمە لێخوڕە خۆکارەکە لەسەر فڕۆکەکە لەسەر ڕێڕەو ھێشتییەوە تەنانەت لە کاتی ھەڵبەز و دابەز.}}
#: {{ux|en|The automatic doors opened as I approached the [[entrance]] to the store.|دەرگا ئۆتۆماتیکییەکان کرانەوە کە گەشتم بە بەردەمی فرۆشگاکە.}}
# ڕوودان بەبێ [[بیرکردنەوە]]
#: {{ux|en|Breathing is an automatic [[function]] of the body.|[[ھەناسەدان]] ئەرکێکی خۆنەویستانەی لەشە.}}
# شتێک کە ھەمیشە ڕوودەدات لە ئەنجامی شتێکدا
#: {{ux|en|A fine for this offence is automatic.|سزا بۆ ئەم تاوانە ھەمیشە ھەیە.}}
==== ناو ====
{{en-noun}}
# [[چەک|چەکێک]] کە خۆی پڕدەکاتەوە [[ھەرچەندە]] دەست لەسەر [[پەلەپیتکە|پەلەپیتکەکە]] دابنێیت
#: {{ux|en|The gunman opened fire with an automatic.|چەکدارەکە بە چەکێکی خۆکار دەستی بە تەقە کرد.}}
# ئۆتۆمبێلێک کە [[خۆکارانە]] گێڕ دەگۆڕێت
#: {{ux|en|Kate drives an automatic.|کەیت ئۆتۆمبێلێکی گێڕ ئۆتۆماتیکی ھەیە.}}
2242tcsb625qxo0fph89d3u6zvexbk3
keep
0
11064
36948
35217
2026-08-18T03:01:49Z
Ghybu
12
/* کردار */
36948
wikitext
text/x-wiki
== ئینگلیزی ==
===گۆکردن===
* {{enPR|kēp}}, {{IPA|en|/kiːp/}}
** {{IPA|en|[kiːp]|[kʰɪjp]|a=RP}}
** {{IPA|en|[kʰɪjp]|a=SSB,Southern US}}
** {{IPA|en|[k̟çi(ː)p]|a=US}}
** {{IPA|en|[k(ʰ)i(ː)p]|a=CA,Scotland}}
* {{audio|en|en-us-keep.ogg|a=US}}
* {{audio|en|en-au-keep.ogg|a=AU}}
* {{rhymes|en|iːp|s=1}}
===کار===
{{head|en|کار}}
# [[پاراستن]]
#: {{ux|en|He kept [[all]] her letters.|تەواوی [[نامە|نامەکانیی]] پاراست.}}
#: {{ux|en|She handed the [[waiter]] a hundred dollar [[bill]] and told him to keep the [[change]].|پارەیەکی ١٠٠ دا بە [[گارسۆن|گارسۆنەکە]] و پێی گوت [[باقی|باقییەکەی]] ھەڵبگرە.}}
# دانان یان [[ھەڵگرتن|ھەڵگرتنی]] شتێک لە شوێنێک
#: {{ux|en|Keep your [[passport]] in a safe place.|پاسپۆرتەکەت لە شوێنێکی [[سەلامەت]] ھەڵبگرە.}}
#: {{ux|en|Where do you keep the [[sugar]]?|شەکرەکە لە کوێ دەدەنێیت؟}}
# ھەبوونی شتێک بۆ کەسێک
#: {{ux|en|Please keep a [[seat]] for me.|تکایە جێگایەکم بۆ بگرە.}}
#: {{ux|en|The man in the shop said he'd keep it for me until Friday.|پیاوەکە لە فرۆشگاکە گوتی بۆم دادەنێت تاوەکو ھەینی.}}
# باوەشمان کرد بە یەکدیدا بۆ مانەوە بە گەرمی
#: {{ux|en|We huddled together to keep warm.|باوەشمان کرد بە یەکدا بۆ مانەوە بە گەرمی.}}
#: {{ux|en|I could not keep silent any longer.|نەمدەتوانی چی دیکە بێدەنگ بم.}}
# بەردەوام بوون لە کردنی شتێک
#: {{ux|en|Keep smiling!|[[بزە]] بکە!}}
#: {{ux|en|Why does everyone keep saying that?|بۆچی ھەموان بەردەوام ئەوە دەڵێن؟}}
# زانینی شتێک و ئەوەی بە کەس نەڵێیت
#: {{ux|en|Can you keep a [[secret]]?|دەتوانیت [[نھێنی]] بپارێزیت؟}}
#: {{ux|en|She kept her [[past]] secret from us all.|ڕابردووی بە نھێنی ھێشتەوە لە ھەموومان.}}
# کردنی ئەوەی کە [[بەڵێن|بەڵێنت]] داوە
#: {{ux|en|She kept her [[promise]] to visit them.|بەڵێنەکەی پاراست بەوەی سەردانیان بکات.}}
#: {{ux|en|Mary kept her word and Henry was never informed.|ماری بەڵێنەکەی پاراست و ھێنری ھەرگیز پێی نەگوترا.}}
# نووسینی شتێک وەک تۆمار
#: {{ux|en|She kept a [[diary]] for over twenty years.|یادنامەیەکی بۆ بیست ساڵ نووسی.}}
#: {{ux|en|Keep a note of where each item can be found.|ئەوە بنووسە کە ھەر شتێک لە کوێیە.}}
# ھەبوونی ئاژەڵ و بەخێوکردنی
#: {{ux|en|My [[grandmother]] kept chickens in her back yard.|داپیرەم مریشکی ھەبوو لە [[حەوشە|حەوشەی]] پشتەوە.}}
#: {{ux|en|Residents are not allowed to keep pets.|ھاوڵاتییەکان ڕێگایان پێنادرێت ئاژەڵی ماڵییان ھەبێت.}}
# ھەبوونی فرۆشگا یان چێشتخانەیەک و بەڕێوەبردنی
#: {{ux|en|Her father kept a grocer's shop.|باوکی فرۆشگایەکی سەوزەفرۆشی ھەبوو.}}
# دابینکردنی ئەوەی کە پێویستە بۆ کەسێک تاوەکو بژی
#: {{ux|en|He scarcely earns enough to keep himself and his family.|بە ئەستەم بەشی پێویست قازانج دەکات بۆ ژیاندنی خۆی و خێزانەکەی.}}
#: {{ux|en|He kept himself by giving private lessons.|خۆی دەژیاند بە گوتنەوەی وانەی تایبەت.}}
# دواخستنی کەسێک
#: {{ux|en|You're an hour late—what kept you?|یەک کاتژمێر دواکەوتوویت ـ چی دوایخستیت؟}}
#: {{ux|en|I won't keep you long. I've just got a [[couple]] of quick questions.|دواتناخەم بۆ زۆر. ژمارەیەک پرسیاری خێرام ھەن.}}
# بۆ باسکردن یان پرسین لە [[تەندروستی]] کەسێک
#: {{ux|en|How is your mother keeping?|تەندروستی دایکت چۆنە؟}}
#: {{ux|en|We're all keeping well.|ھەموومان تەندروستیمان باشە.}}
# مانەوە لە دۆخێکی باش
#: {{ux|en|Milk and cream should keep [[quite]] well in a fridge.|شیر و کرێم دەکرێت زۆر باش لە بەفرگر بمێننەوە.}}
#: {{ux|en|Finish off the banana—it won't keep.|مۆزەکە تەواو بکە ـ باش نامێنێتەوە.}}
# پاراستنی کەسێک لە شتێک
#: {{ux|en|May the Lord bless you and keep you.|خودا ڕەحمت پێبکات و بتپارێزێت.}}
#: {{ux|en|His only [[thought]] was to keep the boy from harm.|تەنھا بیرکردنەوەی ئەوە بوو کوڕەکە لە مەترسی بپارێزێت.}}
====ناو====
# خواردن، [[جلوبەرگ]]، و ھەموو ئەو شتانەی کە کەسێک پێویستییەتی بۆ ژیان
#: {{ux|en|It's about time you got a [[job]] to earn your keep.|لەسەر کات وەستاوە کە کارێک بدۆزیتەوە کە بژێوی خۆت پەیدا بکەیت.}}
# تاوەرێکی گەورەی بەھێز کە وەک بەشێکی قەڵایەکی کۆن درووستکراوە
oeed5d89elmplgc51jomi746a2uaj9a
مۆدیوول:test
828
11481
36914
36909
2026-08-17T21:54:05Z
Ghybu
12
36914
Scribunto
text/plain
function export.test_section()
local frame = mw.getCurrentFrame()
local extension_tag = frame.extensionTag
local nowiki_marker = extension_tag(frame, "nowiki")
local preprocessed = frame:preprocess(
"=" .. nowiki_marker .. "="
)
return "<pre>"
.. "NOWIKI:\n"
.. nowiki_marker
.. "\n\nPREPROCESS:\n"
.. preprocessed
.. "</pre>"
end
2x7areyed37j80ltygauo1x1h08h10u
36915
36914
2026-08-17T21:55:22Z
Ghybu
12
36915
Scribunto
text/plain
function export.get_current_section()
local frame = mw.getCurrentFrame()
local extension_tag = frame.extensionTag
local nowiki_marker = extension_tag(frame, "nowiki")
local preprocessed = frame:preprocess(
"=" .. nowiki_marker .. "="
)
return "<pre>"
.. "NOWIKI:\n"
.. nowiki_marker
.. "\n\nPREPROCESS:\n"
.. preprocessed
.. "</pre>"
end
l0ga7qtamwl0du9g63dbwgoq16yij9i
36916
36915
2026-08-17T21:57:30Z
Ghybu
12
36916
Scribunto
text/plain
local export = {}
function export.get_current_section()
local frame = mw.getCurrentFrame()
local extension_tag = frame.extensionTag
local nowiki_marker = extension_tag(frame, "nowiki")
local preprocessed = frame:preprocess(
"=" .. nowiki_marker .. "="
)
return "<pre>"
.. "NOWIKI:\n"
.. nowiki_marker
.. "\n\nPREPROCESS:\n"
.. preprocessed
.. "</pre>"
end
return export
k26jzbu5neow4ncfy6pcor068ofoen7
36929
36916
2026-08-17T23:47:11Z
Ghybu
12
پەڕەکەی واڵا کردەوە
36929
Scribunto
text/plain
phoiac9h4m842xq45sp7s6u21eteeq1
بەکارھێنەر:Ghybu/test
2
11482
36919
36912
2026-08-17T22:29:16Z
Ghybu
12
36919
wikitext
text/x-wiki
== یەکەم ==
{{#invoke:Pages|get_current_section}}
=== بەش ===
{{#invoke:Pages|get_current_section}}
== دووەم ==
{{#invoke:Pages|get_current_section}}
=== بەش ===
{{#invoke:Pages|get_current_section}}
938zil969mu2m97nbymhqllax4b7iko
36920
36919
2026-08-17T22:35:19Z
Ghybu
12
36920
wikitext
text/x-wiki
== یەکەم ==
{{#invoke:pages|get_current_section}}
=== بەش ===
{{#invoke:pages|get_current_section}}
== دووەم ==
{{#invoke:pages|get_current_section}}
=== بەش ===
{{#invoke:pages|get_current_section}}
tg84pf347i3d79qu3gquy18af0zqd8a
36921
36920
2026-08-17T22:38:11Z
Ghybu
12
36921
wikitext
text/x-wiki
aaaa
{{#invoke:pages|get_current_section}}
o2jnt6avsjuwrwtgfr6me22d9gnh40w
36922
36921
2026-08-17T22:43:51Z
Ghybu
12
پووچەڵکردنەوەی پێداچوونەوەی [[Special:Diff/36921|36921]] لە لایەن [[Special:Contributions/Ghybu|Ghybu]] ([[User talk:Ghybu|لێدوان]])
36922
wikitext
text/x-wiki
aaaa
{{#invoke:pages|get_current_section}}
== یەکەم ==
{{#invoke:pages|get_current_section}}
=== بەش ===
{{#invoke:pages|get_current_section}}
== دووەم ==
{{#invoke:pages|get_current_section}}
=== بەش ===
{{#invoke:pages|get_current_section}}
benmaua1ki5s8ai2gjecl8654nlcmt2
36923
36922
2026-08-17T23:09:36Z
Ghybu
12
36923
wikitext
text/x-wiki
## aaa
{{#invoke:Pages|test}}
## bbb
{{#invoke:Pages|test}}
4poy65x1r4jquqyssdk22m02jh7iszb
36924
36923
2026-08-17T23:09:52Z
Ghybu
12
36924
wikitext
text/x-wiki
## aaa
{{#invoke:pages|test}}
## bbb
{{#invoke:pages|test}}
pma3fm2vescxnhoctg2g62dmirhrdch
36925
36924
2026-08-17T23:22:52Z
Ghybu
12
36925
wikitext
text/x-wiki
== French ==
{{#invoke:pages|test}}
=== Noun ===
{{#invoke:pages|test}}
== English ==
{{#invoke:pages|test}}
=== Noun ===
{{#invoke:pages|test}}
4a5tllie89ffggu43c2ynyykzezq0v8
36928
36925
2026-08-17T23:46:47Z
Ghybu
12
پەڕەکەی واڵا کردەوە
36928
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
بەکارھێنەر:Ghybu/test2
2
11483
36926
2026-08-17T23:30:42Z
Ghybu
12
...
36926
wikitext
text/x-wiki
do
local current_section
function export.get_current_section()
if current_section ~= nil then
return current_section
end
local frame = parent_frame or get_parent_frame()
while frame do
if find(frame:getTitle(), "^Module:") then
current_section = 0
return 0
end
frame = frame:getParent()
end
local current = current_frame or get_current_frame()
local extension_tag = current.extensionTag
-- CKB: an empty nowiki does not produce a marker.
-- Therefore, we give it some content.
local nowiki_marker = extension_tag(
current,
"nowiki",
"CKBSEC"
)
-- Generate an artificial heading and retrieve its number.
local h = tonumber(match(
current:preprocess("=" .. nowiki_marker .. "="),
"\127'\"`UNIQ%-%-h%-(%d+)%-%-QINU`\"'\127"
))
if not h then
current_section = 0
return 0
end
-- Retrieve the number of the nowiki marker.
local n, offset = tonumber(match(
nowiki_marker,
"\127'\"`UNIQ%-%-nowiki%-([%dA-F]+)%-QINU`\"'\127"
), 16)
-- Search for the offset in previous markers.
while not offset and n > 0 do
n = n - 1
offset = match(
unstrip_nowiki(
format(
"\127'\"`UNIQ--nowiki-%08X-QINU`\"'\127",
n
)
),
"^CKBSEC\1(%d+)"
)
end
offset = offset and tonumber(offset) or 0
-- Store the offset.
extension_tag(
current,
"nowiki",
"CKBSEC\1" .. offset
)
-- On ckb, the first generated heading is h = 0.
-- MediaWiki sections start at 1.
current_section = h - offset + 1
return current_section
end
get_current_section = export.get_current_section
end
9jnkvyt0bkj8zmru7ga7c3nbgmx7cum
36927
36926
2026-08-17T23:46:33Z
Ghybu
12
پەڕەکەی واڵا کردەوە
36927
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
پۆل:ناوەکان بەپێی زمان
14
11484
36934
2026-08-18T00:30:29Z
Ghybu
12
پەڕەی دروست کرد بە «{{auto cat}}»ەوە
36934
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
پۆل:Pages using catfix
14
11485
36935
2026-08-18T00:36:47Z
Ghybu
12
پەڕەی دروست کرد بە «{{auto cat}}»ەوە
36935
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
پۆل:لێما
14
11486
36936
2026-08-18T01:02:34Z
Ghybu
12
پەڕەی دروست کرد بە «{{auto cat}}»ەوە
36936
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
36937
36936
2026-08-18T01:11:05Z
Ghybu
12
36937
wikitext
text/x-wiki
{{delete}}
35r2j9t4ectnt1cmb7mlgcqvwz6h5k6
پۆل:لێماکان بەپێی زمان
14
11487
36938
2026-08-18T01:12:11Z
Ghybu
12
پەڕەی دروست کرد بە «{{cat bike}}»ەوە
36938
wikitext
text/x-wiki
{{cat bike}}
9n8zc4l476sseevvv6gc4tgsxplgezt
36939
36938
2026-08-18T01:12:30Z
Ghybu
12
36939
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
پۆل:ھاوەڵناوەکان بەپێی زمان
14
11488
36945
2026-08-18T02:01:59Z
Ghybu
12
پەڕەی دروست کرد بە «{{auto cat}}»ەوە
36945
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
پۆل:کارەکان بەپێی زمان
14
11489
36946
2026-08-18T02:02:25Z
Ghybu
12
پەڕەی دروست کرد بە «{{auto cat}}»ەوە
36946
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx