跳转到内容

模組:Conversion rule extractor

本页使用了标题或全文手工转换
维基百科,自由的百科全书

这是本页的一个历史版本,由PexEric留言 | 贡献2025年5月3日 (六) 15:02 建立内容为“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 -- 公共转换组查找上限 --[[---------------…”的新页面)编辑。这可能和当前版本存在着巨大的差异。

(差异) ←上一修订 | 最后版本 (差异) | 下一修订→ (差异)

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