模組:Conversion rule extractor
外观

![]() | 此模块已评为alpha版,可接受第三方输入,并可用于少量页面以检查是否存在问题,但需要受到检查。欢迎提供新功能或修改其输入输出机制的建议。 |
![]() | 此模块使用Lua语言: |
本模块用于提取指定页面的字词转换规则(包括手动规则和公共转换组规则),并根据需要筛选出能在特定目标页面或标题上匹配使用的规则,最终以不同格式输出。
子模块
- Module:Conversion_rule_extractor/Extractor – 用于提取规则
- Module:Conversion_rule_extractor/Matcher – 用于匹配规则
函数
getRules
获取指定来源页面的所有内容转换规则(手动+公共组),并筛选出能在目标页面内容中匹配到的规则。
调用方式: {{#invoke:Conversion_rule_extractor|getRules|from=来源页面|to=目标页面|flag=输出格式}}
参数:
- from 或匿名参数 1: (必须) 字符串,规则来源页面的标题。
- to: (可选) 字符串,用于匹配规则的目标页面标题。默认为调用模块的当前页面。
- flag: (可选) 字符串,指定输出规则的旗标。
- H (默认): 输出为
-{H|规则;}-
格式。 - raw: 直接输出规则文本,每条规则占一行。
- 其他值 (如 A, D): 输出为
-{值|规则;}-
格式。
- H (默认): 输出为
返回值: 字符串,格式化后的、能在目标页面匹配到的内容转换规则。如果来源页不存在或无匹配规则,返回空字符串。如果缺少 from 参数,返回错误提示信息。
getTitleRule
获取应用于指定来源页面标题的转换规则。
- 如果来源页面有显式的标题 (T) 规则,则使用该规则。
- 如果没有显式标题规则,则尝试将来源页面的所有内容规则与其标题文本进行匹配,使用匹配到的规则。
调用方式: {{#invoke:Conversion_rule_extractor|getTitleRule|from=来源页面|flag=输出格式|type=输出类型}}
参数:
- from 或匿名参数 1: (必须) 字符串,规则来源页面的标题。
- flag: (可选) 字符串,指定输出规则的旗标(当type不为context时生效)。
- H (默认): 输出为
-{H|规则;}-
格式。 - raw: 直接输出规则文本,每条规则占一行。
- 其他值: 输出为
-{值|规则;}-
格式。如果规则来源于内容规则匹配,即使指定flag='T',也会强制使用H。
- H (默认): 输出为
- type: (可选) 字符串,指定输出类型。
- context: (特殊模式) 如果存在显式T规则,输出为
-{T规则;}-
。如果不存在显式T规则,但有内容规则匹配标题,输出为-{H|匹配的内容规则;}-原始标题
。 - 其他值或省略: 按flag参数指定的格式输出规则本身。
- context: (特殊模式) 如果存在显式T规则,输出为
返回值: 字符串,格式化后的标题转换规则或带规则的标题文本。如果来源页不存在或无适用规则,返回空字符串。如果缺少from参数或来源页不存在,返回错误提示信息。
参见
- {{NoteTA-lite}}
local p = {}
local TPV = require('Module:Template parameter value')
-- 以下模板的重定向检索于2025-05-03
local NOTE_TA_TEMPLATES = {
'NoteTA', 'TA', 'NoteAT', 'NoteTA/default', 'NOTETA', 'Note TA', 'Noteta', 'NoteTa', 'NoteTA/lua', '全文字词转换',
'NoteTA-lite', 'TA-lite', 'TAL', 'TAl'
}
local MAX_LOCAL_RULES = 30 -- 本地规则查找上限
local MAX_GROUP_RULES = 30 -- 公共转换组查找上限
--[[--------------------------< 辅助函数 >--------------------------]]
-- 安全地加载 CGroup 模块数据
local function loadCGroupData(groupName)
local moduleTitleStr = 'Module:CGroup/' .. groupName
local success, data
-- 先检查模块页面是否存在,避免日志中出现不必要的 loadData 错误
local titleObj = mw.title.new(moduleTitleStr)
if titleObj and titleObj.exists then
success, data = pcall(mw.loadData, moduleTitleStr)
if success and type(data) == 'table' then
return data
else
-- 可选:记录错误
-- mw.log('无法加载或解析 CGroup 模块:' .. moduleTitleStr)
return nil
end
end
return nil
end
-- 从加载的 CGroup 数据中提取规则
local function extractRulesFromCGroupData(data)
local rules = {}
if data and data.content and type(data.content) == 'table' then
for _, item in ipairs(data.content) do
-- 检查是否为标准项目规则且包含 rule 字符串
if type(item) == 'table' and item.type == 'item' and type(item.rule) == 'string' and item.rule ~= '' then
table.insert(rules, item.rule)
end
end
end
return rules
end
--[[
-- @description 内部函数,用于从页面上的第一个 NoteTA 模板获取所有相关规则。
-- @param pageTitleString string 页面标题字符串。
-- @return table|nil 包含标题、本地和组规则的表,如果未找到模板或出错则返回 nil。
-- 格式: {
-- title = "规则字符串" or nil,
-- ['local'] = { "规则1", "规则2", ... } or {}, -- 使用 ['local'] 避免关键字冲突
-- groups = { { name="G1名称", rules={"规则A", ...} }, { name="G2名称", rules={"规则B", ...} } ... } or {}
-- }
--]]
function p._internal_fetchAllRules(pageTitleString)
local allRules = {
title = nil,
['local'] = {}, -- 修正:使用 ['local'] 避免关键字冲突
groups = {}
}
local foundTemplate = false
-- 1. 获取标题规则 (T)
local success_t, titleRule = TPV.getParameter(pageTitleString, NOTE_TA_TEMPLATES, 'T')
if success_t and titleRule and titleRule ~= '' then
allRules.title = titleRule
foundTemplate = true -- 如果 T 存在,说明找到了模板
end
-- 2. 获取本地规则 (1..MAX_LOCAL_RULES)
for i = 1, MAX_LOCAL_RULES do
local paramName = tostring(i)
local success_l, localRule = TPV.getParameter(pageTitleString, NOTE_TA_TEMPLATES, paramName)
if success_l and localRule and localRule ~= '' then
table.insert(allRules['local'], localRule) -- 修正:使用 allRules['local']
foundTemplate = true -- 存在规则参数,说明找到了模板
elseif not success_l then
-- 如果 TPV.getParameter 因 "No valid template found" 以外的原因失败,
-- 可能表示页面或模块有问题。但最常见的情况是数字参数用完了。
-- 如果 T 或任何 G 存在,我们知道模板存在。
-- 如果 T 和 G 都不存在,且此处 getParameter 失败,则说明页面上没有模板。
if localRule == "No valid template found" and not foundTemplate then
return nil -- 页面上完全没有找到模板
end
-- 优化:如果一个数字参数缺失,后续的也不太可能存在。
-- 但为确保健壮性,我们继续检查到 MAX_LOCAL_RULES。
end
end
-- 3. 获取组规则 (G1..MAX_GROUP_RULES)
for i = 1, MAX_GROUP_RULES do
local paramName = 'G' .. i
local success_g, groupName = TPV.getParameter(pageTitleString, NOTE_TA_TEMPLATES, paramName)
if success_g and groupName and groupName ~= '' then
foundTemplate = true -- 存在组参数,说明找到了模板
local groupData = loadCGroupData(groupName)
if groupData then
local groupRules = extractRulesFromCGroupData(groupData)
if #groupRules > 0 then
table.insert(allRules.groups, {
name = groupName,
rules = groupRules
})
end
else
-- 可选:记录无法加载的组模块
-- mw.log('页面 ' .. pageTitleString .. ' 上的 NoteTA 请求了不存在/无效的 CGroup: ' .. groupName)
end
elseif not success_g then
if groupName == "No valid template found" and not foundTemplate then
return nil -- 页面上完全没有找到模板
end
-- 类似本地规则的逻辑,为确保健壮性继续检查所有 G 参数。
end
end
-- 如果找到了任何规则(T、本地或组),则返回结构;否则返回 nil
if foundTemplate then
return allRules
else
-- 处理页面没有 NoteTA 模板或 TPV 最初就失败的情况
return nil
end
end
--[[--------------------------< 公开函数 >--------------------------]]
--[[
-- @description 获取页面上第一个 NoteTA 模板的所有全文转换规则。
-- 包括本地规则(数字参数)和组规则(G参数)。
-- 注意:这些规则 *也* 作用于标题。
-- @param pageTitle string|mw.title 页面标题对象或字符串表示。
-- @return table|nil 包含本地和组规则的表,如果未找到规则/出错则返回 nil。
-- 格式: {
-- ['local'] = { "规则1", "规则2", ... } or {}, -- 使用 ['local']
-- groups = { { name="G1名称", rules={"规则A", ...} }, { name="G2名称", rules={"规则B", ...} } ... } or {}
-- }
--]]
function p.getFullTextRules(pageTitle)
local pageTitleString
if type(pageTitle) == 'string' then
pageTitleString = pageTitle
elseif type(pageTitle) == 'userdata' and getmetatable(pageTitle) == 'mw.title' then
pageTitleString = pageTitle.fullText
else
error("无效的 pageTitle 类型。需要字符串或 mw.title 对象。", 2)
return nil
end
local allRules = p._internal_fetchAllRules(pageTitleString)
if allRules then
-- 对于“全文规则”,仅返回本地和组规则
return {
['local'] = allRules['local'], -- 修正:使用 ['local']
groups = allRules.groups
}
else
return nil -- 未找到模板或规则
end
end
--[[
-- @description 获取页面上第一个 NoteTA 模板的所有作用于页面标题的规则。
-- 包括特定的标题规则(T参数)、本地规则(数字参数)
-- 和组规则(G参数),因为全文规则也影响标题。
-- @param pageTitle string|mw.title 页面标题对象或字符串表示。
-- @return table|nil 包含标题、本地和组规则的表,如果未找到规则/出错则返回 nil。
-- 格式: {
-- title = "规则字符串" or nil,
-- ['local'] = { "规则1", "规则2", ... } or {}, -- 使用 ['local']
-- groups = { { name="G1名称", rules={"规则A", ...} }, { name="G2名称", rules={"规则B", ...} } ... } or {}
-- }
--]]
function p.getTitleRules(pageTitle)
local pageTitleString
if type(pageTitle) == 'string' then
pageTitleString = pageTitle
elseif type(pageTitle) == 'userdata' and getmetatable(pageTitle) == 'mw.title' then
pageTitleString = pageTitle.fullText
else
error("无效的 pageTitle 类型。需要字符串或 mw.title 对象。", 2)
return nil
end
-- 对于标题规则,我们返回 *所有* 提取的规则(T、本地、组)
-- 因为本地和组规则也作用于标题。
return p._internal_fetchAllRules(pageTitleString) -- 返回值已包含 ['local']
end
--[[--------------------------< 模板入口点 >--------------------------]]
-- 模板使用示例入口点 (例如, {{#invoke:ConversionRuleExtractor|getFullText|页面标题}})
function p.getFullText(frame)
local args = require('Module:Arguments').getArgs(frame)
local page = args[1] or args.page
if not page or page == '' then
return '<span class="error">错误:必须提供页面标题。</span>'
end
local rules = p.getFullTextRules(page)
if rules then
-- 返回格式化表示(例如,使用 mw.dumpObject 进行调试)
-- 或将其格式化为 wikitext 列表等以供显示。
-- return mw.dumpObject(rules) -- mw.dumpObject 会正确处理 ['local']
-- 示例 wikitext 输出:
local output = {}
table.insert(output, "*'''本地规则:'''")
if rules['local'] and #rules['local'] > 0 then -- 修正:检查 rules['local']
for _, rule in ipairs(rules['local']) do table.insert(output, "** " .. rule) end -- 修正:迭代 rules['local']
else table.insert(output, "** (无)") end
table.insert(output, "*'''公共转换组规则:'''")
if rules.groups and #rules.groups > 0 then
for _, group in ipairs(rules.groups) do
table.insert(output, "** 组: " .. group.name)
for _, rule in ipairs(group.rules) do table.insert(output, "*** " .. rule) end
end
else table.insert(output, "** (无)") end
return table.concat(output, "\n")
else
return "''未找到全文转换规则或页面/模板错误。''"
end
end
-- 模板使用示例入口点 (例如, {{#invoke:ConversionRuleExtractor|getTitle|页面标题}})
function p.getTitle(frame)
local args = require('Module:Arguments').getArgs(frame)
local page = args[1] or args.page
if not page or page == '' then
return '<span class="error">错误:必须提供页面标题。</span>'
end
local rules = p.getTitleRules(page)
if rules then
-- 返回格式化表示
-- return mw.dumpObject(rules) -- mw.dumpObject 会正确处理 ['local']
-- 示例 wikitext 输出:
local output = {}
table.insert(output, "*'''标题规则 (T):''' " .. (rules.title or "(无)"))
table.insert(output, "*'''本地规则 (亦作用于标题):'''")
if rules['local'] and #rules['local'] > 0 then -- 修正:检查 rules['local']
for _, rule in ipairs(rules['local']) do table.insert(output, "** " .. rule) end -- 修正:迭代 rules['local']
else table.insert(output, "** (无)") end
table.insert(output, "*'''公共转换组规则 (亦作用于标题):'''")
if rules.groups and #rules.groups > 0 then
for _, group in ipairs(rules.groups) do
table.insert(output, "** 组: " .. group.name)
for _, rule in ipairs(group.rules) do table.insert(output, "*** " .. rule) end
end
else table.insert(output, "** (无)") end
return table.concat(output, "\n")
else
return "''未找到标题转换规则或页面错误。''"
end
end
return p