跳转到内容

模組:Vgtn

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

这是本页的一个历史版本,由For Each ... Next留言 | 贡献2025年1月20日 (一) 08:01 建立内容为“require('strict') local getArgs = require('Module:Arguments').getArgs local p = {} local rule_data = require('Module:Vgtn/data').data local function get_rule(rules, original, lang) --[==[根据原文名和语言代码,从译名规则表中获取符合条件的首条规则。 指定语言代码时,返回原文名、语言标签皆匹配的首条定义项。 未指定语言代码时,返回与原文名匹配的首条定义项…”的新页面)编辑。这可能和当前版本存在着巨大的差异。

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

require('strict')
local getArgs = require('Module:Arguments').getArgs
local p = {}

local rule_data = require('Module:Vgtn/data').data

local function get_rule(rules, original, lang)
    --[==[根据原文名和语言代码,从译名规则表中获取符合条件的首条规则。
    指定语言代码时,返回原文名、语言标签皆匹配的首条定义项。
    未指定语言代码时,返回与原文名匹配的首条定义项。
    若无匹配项,则返回只有原文名(和语言代码)而无译名定义的空规则。

    :param rules: 由译名规则构成的表。
    :param original: 所查询的原文名。
    :param lang: 原文名语言代码,可缺省。
    :return: 一条译名定义规则。

    示例
    ----

    >>> local data = {
    >>>     { 'Arend', lang = 'de', cn = '阿伦德·雅各布斯' },
    >>>     { 'Arend', lang = 'en', cn = '阿伦·雅各布斯' },
    >>> }

    >>> get_datum(data, 'Arend Jacobs', 'en')
    { 'Arend', lang = 'en', cn = '阿伦·雅各布斯' },
    >>> get_datum(data, 'Arend')  -- 符合条件的首项结果
    { 'Arend', lang = 'de', cn = '阿伦德·雅各布斯' },
    >>> get_datum(data, 'Arend', 'fr')  -- 查无此名称的法语定义,返回空规则
    { 'Arend', lang = 'fr' },
    >>> get_datum(data, 'Kamisato Ayaka') -- 查无此原名,返回空规则
    { 'Kamisato Ayaka' },
    ]==]

    for _, rule in ipairs(rules) do
        if (original == datum[1]) and (lang == nil or lang == datum.lang) then
            return rule
        end
    end
    return { original, lang = lang }
end

local function get_part_name(name, part, sep)
    --[==[提取姓名的指定部分。主要用于处理地区词转换时,只需要写姓氏的问题。

    :param name: 待提取的姓名全名。
    :param part: 所提取的部分索引,为`nil`时返回全名。预设为`nil`。
    :param sep: 分隔符。预设为中文间隔号('·'),但若姓名中不含间隔号时为空格(' ')。
    :return: 所提取的姓名片段。

    示例
    ----

    >>> get_part_name('杰里米·帕里什', 2)
    '帕里什'
    >>> get_part_name('John D. Carmack', 3, ' ') -- 省略第三参数亦可得出结果
    'Carmack'
    ]==]

    if name == nil or part == nil then
        return name
    end
    if sep then
        return mw.text.split(name, sep, true)[part]
    elseif mw.ustring.find(name, '·') then
        return mw.text.split(name, '·', true)[part]
    else
        return mw.text.split(name, ' ', true)[part]
    end
end

local function parse_translation(rule, part, sep)
    --[==[将译名定义规则中译名部分解释为维基代码,可根据分隔符取姓名片段。

    若简体(`cn`、`sg`、`my`)和繁体(`tw`、`hk`、`mo`)两类译名均有定义,则返回内联转换代码`-{zh-xx:...;}-`。
    若仅定义其中一种书写体系下的译名,则返回普通文字。
    若未定义任何中文译名,则返回nil。

    :param rule: 译名定义规则。
    :param part: 所提取的姓名片段编号。例如对于译名'约翰·D·卡马克',可输入3仅列出'卡马克'。
    :param sep: 片段的分隔符。预设为中文间隔号('·'),但若姓名中不含间隔号时为空格(' ')。
    :return: 译名规则中译名部分对应的维基代码。

    示例
    ----

    >>> rule = { 'Jeremy Parish', cn = '杰里米·帕里什', hk = '謝洛美·巴里殊', tw = '傑瑞米·派瑞許' }
    >>> parse_translation(rule)
    -{zh-cn:杰里米·帕里什; zh-hk:謝洛美·巴里殊; zh-tw:傑瑞米·派瑞許;}-
    >>> parse_translation(rule, 2)
    -{zh-cn:帕里什; zh-hk:巴里殊; zh-tw:派瑞許;}-

    >>> -- 仅定义一种译名,不启用内联字词转换
    >>> local rule = { 'John Carmack', lang='en', cn = '约翰·D·卡马克' }
    >>> parse_translation(rule)
    约翰·D·卡马克
    >>> parse_translation(rule, 3)
    卡马克

    >>> -- 未定义简繁两种体系下的译名,故依然无法地区词转换,只生成了其中一种译名的普通文本。
    >>> local rule = { 'Jeremy Parish', hk = '謝洛美·巴里殊', tw = '傑瑞米·派瑞許' }
    >>> parse_translation(rule)
    傑瑞米·派瑞許

    >>> -- 完全未定义中文译名
    >>> rule = { 'Jeremy Parish' }
    >>> parse_translation(rule)
    nil
    ]==]

    local varieties = {}
    local hant_variety_names, hant_flag = { 'tw', 'hk', 'mo' }, false
    local hans_variety_names, hans_flag = { 'cn', 'sg', 'my' }, false
    for _, v in ipairs(hant_variety_names) do
        if rule[v] then
            table.insert(varieties, { label = 'zh-' .. v, value = get_part_name(rule[v], part, sep) })
            hant_flag = true
        end
    end
    for _, v in ipairs(hans_variety_names) do
        if rule[v] then
            table.insert(varieties, { label = 'zh-' .. v, value = get_part_name(rule[v], part, sep) })
            hans_flag = true
        end
    end

    if #varieties == 0 then
        return nil
    end
    if not (hans_flag and hant_flag) then
        return varieties[1].value
    end

    local result_fragments = {}
    -- 内联转换定义按变种代码列出(强迫症)
    table.sort(varieties, function(a, b)
        return a.label < b.label
    end)
    for _, variety in ipairs(varieties) do
        table.insert(result_fragments, variety.label .. ':' .. variety.value .. ';')
    end
    local result = table.concat(result_fragments, ' ')
    result = '-{' .. result .. '}-'
    return result
end

local function parse_original(rule, part, sep)
    --[==[将译名定义规则中的原名部分解释为维基代码,可根据分隔符取姓名片段。

    若定义原名的语言(`lang`),则套用{{lang}}模板生成语义规范的外文名。
    若未定义原名的语言,则只用语言转换标签包裹原文`-{...}-`,避免可能的过度字词转换。

    :param rule: 译名定义规则。
    :param part: 所提取的姓名片段编号。例如对于原名'John D. Carmack',输入3可仅提取'Carmack'。
    :param sep: 片段的分隔符。预设为中文间隔号('·'),但若姓名中不含间隔号时为空格(' ')。
    :return: 译名规则中原名部分对应的维基代码。

    示例
    ----

    >>> local rule = { 'John D. Carmack', lang='en', cn = '约翰·D·卡马克' }
    >>> parse_original(rule)
    {{lang|en|John D. Carmack}}
    >>> parse_translation(rule, 3)
    {{lang|en|Carmack}}

    >>> -- 未指定语言代码
    >>> rule = { '浜崎あゆみ', tw = '濱崎步' }
    >>> parse_translation(rule)
    -{浜崎あゆみ}-
    ]==]

    local original, lang = get_part_name(rule[1], part, sep), rule.lang
    if lang == nil then
        return '-{' .. original .. '}-'
    end
    return mw.getCurrentFrame():expandTemplate { title = 'Lang', args = { lang, original } }
end

local function parse_rule(rules, part, sep, bracket)
    --[==[将译名定义规则解析为维基代码

    :param rule: 译名定义规则。
    :param part: 所提取的姓名片段编号。例如对于译名'约翰·D·卡马克',可输入3仅列出'卡马克'。
    :param sep: 片段的分隔符。预设为中文间隔号('·'),但若姓名中不含间隔号时为空格(' ')。
    :param bracket: 是否括号加注外文原名,填'no'则不加注,其他情况下为标注。预设为`True`。
    :return: 译名规则对应的维基代码。

    示例
    ----

    >>> local rule = { 'Jeremy Parish', lang='en', cn = '杰里米·帕里什', hk = '謝洛美·巴里殊', tw = '傑瑞米·派瑞許' }
    >>> parse_rule(rule)
    -{zh-cn:杰里米·帕里什; zh-hk:謝洛美·巴里殊; zh-tw:傑瑞米·派瑞許;}-({{lang|en|Jeremy Parish}})
    >>> parse_rule(rule, 2)
    -{zh-cn:帕里什; zh-hk:巴里殊; zh-tw:派瑞許;}-({{lang|en|Parish}})
    >>> parse_rule(rule, 2, nil, 'no')
    -{zh-cn:帕里什; zh-hk:巴里殊; zh-tw:派瑞許;}-
    ]==]

    bracket = (bracket == nil) and true or bracket
    local original = parse_original(rules, part, sep)
    local translation = parse_translation(rules, part, sep)

    if translation == nil then
        return original
    end
    if bracket == 'no' then
        return translation
    end
    return translation .. '(' .. original .. ')'
end

function p.main(frame)
    local args = getArgs(frame)
    return p._main(args)
end

function p._main(args)
	local rules = rule_data
	local rule = get_rule(rules, args[1], args.lang)
    return parse_rule(rule,args.part, args.sep, args.bracket)
end

return p