local export = {}
local mzh = require("Module:Zh")
-- 簡轉繁
local function st(title)
local script = mzh.ts_determ(title)
if script == 'trad' then return title end
require("Module:debug").track("auto cat/簡體字分類名")
return mzh.st(title):gsub('裡', '里')
end
-- Used in multiple places; create a variable for ease in testing.
local poscatboiler_submodule = "poscatboiler/sandbox"
local function splitLabelLang(titleObject)
local getByCanonicalName = require("Module:languages").getByCanonicalName
local title = titleObject.text
local lang, canonicalName
local preLabel, posLabel = mw.ustring.match(title, "^(.+[^羅]的)(.+)$")
preLabel = preLabel or ''
posLabel = posLabel or title
-- Progressively remove characters from the end of the category name until it matches a language.
for i = mw.ustring.len(posLabel), 1, -1 do
canonicalName = mw.ustring.sub(posLabel, 1, i)
lang = getByCanonicalName(canonicalName)
if lang then
posLabel = posLabel:sub(#canonicalName + 1)
break
end
end
return preLabel .. posLabel, lang
end
-- Add the arguments in `source` to those in `receiver`, offsetting numeric arguments by `offset`.
local function add_args(receiver, source, offset)
for k, v in pairs(source) do
if type(k) == "number" then
receiver[k + offset] = v
else
receiver[k] = v
end
end
return receiver
end
-- List of handler functions that try to match the page name.
-- A handler should return a table of template title plus arguments
-- that is passed to frame:expandTemplate.
-- If a handler does not recognise the page name, it should return nil.
-- Note that the order of functions matters!
local handlers = {}
local function add_handler(func)
table.insert(handlers, func)
end
-- Letter names
add_handler(function(titleObject)
if not titleObject.text:find("letter names$") then
return nil
end
local langCode = titleObject.text:match("^([^:]+):")
local lang, cat
if langCode then
lang = require("Module:languages").getByCode(langCode) or error('The language code "' .. langCode .. '" is not valid.')
cat = titleObject.text:match(":(.+)$")
else
cat = titleObject.text
end
return {title = "topic cat", args = {lang and lang:getCode() or nil, cat}}
end)
-- letter cat
add_handler(function(titleObject)
-- Only recognize cases consisting of an uppercase letter followed by the
-- corresponding lowercase letter, either as the entire category name or
-- followed by a colon (for cases like [[Category:Gg: ⠛]]). Cases that
-- don't fit this profile (e.g. for Turkish [[Category:İi]] and
-- [[Category:Iı]]) need to call {{letter cat}} directly. Formerly this
-- handler was much less restrictive and would fire on categories named
-- [[Category:zh:]], [[Category:RFQ]], etc.
local upper, lower = mw.ustring.match(titleObject.text, "^(%u)(%l)%f[:%z]")
if not upper or mw.ustring.upper(lower) ~= upper then
return nil
end
return {title = "letter cat"}
end)
-- poscatboiler lang-specific and topical categories
add_handler(function(titleObject, args)
local label, lang = splitLabelLang(titleObject)
if lang and label ~= '' then
if label:match("^ ") then
return {title = "topic cat", args = {lang:getCode(), label:sub(2)}}
end
local script, baseLabel = label:match("以(.-)書寫的(.+)$")
if script and baseLabel ~= "terms" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return {title = poscatboiler_submodule, args = add_args({lang:getCode(), baseLabel, scriptObj:getCode()}, args, 3)}, true
end
end
return {title = poscatboiler_submodule, args = add_args({lang:getCode(), label}, args, 3)}, true
end
end)
-- topic cat
add_handler(function(titleObject)
return {title = "topic cat", args = {nil, titleObject.text}}
end)
-- poscatboiler raw handlers
add_handler(function(titleObject, args)
local args = add_args({nil, titleObject.text}, args, 3)
args.raw = true
return {
title = poscatboiler_submodule,
args = args,
}, true
end)
-- poscatboiler umbrella handlers
add_handler(function(titleObject, args)
local args = add_args({nil, titleObject.text}, args, 3)
return {
title = poscatboiler_submodule,
args = args,
}, true
end)
function export.show(frame)
local args = frame:getParent().args
local tempTitleObject = mw.title.getCurrentTitle()
local titleObject = mw.title.new(st(tempTitleObject.prefixedText))
if titleObject.nsText == "Template" then
return "(本模板應該用於Category:命名空間頁面。)"
elseif titleObject.nsText ~= "Category" then
error("本模板/模組只能用於Category:命名空間頁面。")
end
local function extra_args_error(templateObject)
local numargstext = {}
local argstext = {}
local maxargnum = 0
for k, v in pairs(templateObject.args) do
if type(v) == "number" and v > maxargnum then
maxargnum = v
else
table.insert(numargstext, "|" .. k .. "=" .. v)
end
end
for i = 1, maxargnum do
local v = templateObject.args[i]
if v == nil then
v = "(nil)"
elseif v == true then
v = "(true)"
elseif v == false then
v = "(false)"
end
table.insert(argstext, "|" .. v)
end
error("Extra arguments to {{auto cat}} not allowed for this category (recognized as {{[[Template:" ..
templateObject.title .. "|" .. templateObject.title .. "]]" .. numargstext .. argstext .. "}}")
end
local first_error_templateObject, first_error_args_handled, first_error_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 handler for {{poscatboiler}} 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, {{topic cat}} will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
local templateObject, args_handled = handler(titleObject, args)
if templateObject then
require("Module:debug").track("auto cat/" .. templateObject.title)
local cattext = frame:expandTemplate(templateObject)
-- FIXME! We check for specific text found in most or all error messages generated
-- by category tree templates (in particular, the second piece of text below should be
-- in all error messages generated when a given module doesn't recognize a category name).
-- If this text ever changes in the source modules (e.g. [[Module:category tree]],
-- it needs to be changed here as well.)
if cattext:find("Category:標籤無效的分類") or
cattext:find("本分類自動產生的內容有錯誤") then
if not first_error_cattext then
first_error_templateObject = templateObject
first_error_args_handled = args_handled
first_error_cattext = cattext
end
else
if not args_handled and next(args) then
extra_args_error(templateObject)
end
return cattext
end
end
end
if first_error_cattext then
if not first_error_args_handled and next(args) then
extra_args_error(first_error_templateObject)
end
return first_error_cattext
end
error("{{auto cat}}無法識別此分類名稱的格式")
end
-- test function for injecting title string
function export.test(title)
if type(title) == "table" then
title = title:getParent().args[1]
end
local titleObject = {}
titleObject.text = title
for _, handler in ipairs(handlers) do
local t = handler(titleObject)
if t then
return t.title
end
end
end
-- for [[Module:Category tree]]
function export.st(title) return st(title) end
return export