• 欢迎来到THBWiki!如果您是第一次来到这里,请点击右上角注册一个帐户
  • 有任何意见、建议、求助、反馈都可以在 讨论板 提出
  • THBWiki以专业性和准确性为目标,如果你发现了任何确定的错误或疏漏,可在登录后直接进行改正

模块:对话表引用

提供:THBWiki
ナビゲーションに移動 検索に移動
Lua-Logo.svg 模块文档[创建]
local tttools = require('Module:tttools')
local ArgsTracker = require('Module:checkargs').ArgsTracker

local template_name = '模板:对话表引用'

local function errmsg(message)
    return require('Module:error')._main{ message, template_name }
end

-- 格式字符串中允许使用的代号, 以及相应的变体
local allow = {
    char = {
        'char',
        'bbsharp',
        'bbcloudgray',
        'bbcloud'
    },
    ja = {'ja'},
    zh = {'zh'}
}

local normalize = {}
for k, v in pairs(allow) do
    for _, i in pairs(v) do
        normalize[i] = k
    end
end

local function select_paragraphs(text, start, stop)
    local splited = mw.text.split(text, '\n%s*\n+')
    local result = {}
    for i = start, stop do
        table.insert(result, splited[i])
    end
    return table.concat(result, '\n\n')
end

local p = {}

function p._main(args)
    local page = args[1]
    local section = mw.text.trim(args[2] or '')
    local row_num = mw.text.trim(args[3] or '')
    local para_num = mw.text.trim(args[4] or '')
    local format = args.format or args['格式'] or '; char : zh'
    local newline = args.newline or args['换行'] or args['换行符'] or '<br />'
    local sep = args.sep or args['分隔'] or args['分隔符'] or '\n'
    local plain = args.plain or args['纯文本']
    local source_link = args['source link'] or args['原文链接']

    -- 模板可以输入 \n 表示换行
    format = format:gsub('\\n', '\n')
    newline = newline:gsub('\\n', '\n')
    sep = sep:gsub('\\n', '\n')

    if not page then
        return errmsg('错误:没有指定引用的页面名')
    end

    if para_num ~= '' then
        if not row_num:match('^%d+$') then
            return errmsg('错误:只有在给定单一行号(第 3 个参数)时才能进一步指定段落(第 4 个参数)')
        end
        local a, b = para_num:match('^%s*(%d+)%s*%-%s*(%d+)%s*$')
        if a then
            a, b = tonumber(a), tonumber(b)
        else
            a = tonumber(para_num)
            b = a
        end
        if not a then
            return errmsg('错误:段落指定(第 4 个参数)的格式需要形如 2 或 2-3')
        end
        para_num = {a, b}
    end

    local content = tttools.get_content{ page, section, row_num, table.concat(allow.char, ',') }

    if #content == 0 then
        return errmsg('警告:引用的内容不存在')
    end

    local output = {}
    for _, row in ipairs(content) do
        local template = format
        for k, v in pairs(row) do
            k = normalize[k]
            if k then
                v = v:gsub('%s+$', '')
                if #para_num == 2 and k ~= 'char' then
                    v = select_paragraphs(v, unpack(para_num))
                    if v == '' then
                        return errmsg('警告:引用的内容不存在')
                    end
                end
                if plain then
                    v = v:gsub('<[^>]+>', ''):gsub("''+", "")
                end
                v = v:gsub('\n+', newline)
                if k == 'ja' then
                    v = '<span lang="ja">' .. v .. '</span>'
                end
                template = template:gsub(k, v)
            end
        end
        table.insert(output, template)
    end

    local text = table.concat(output, sep)

    if source_link then
        local anchor = ''
        if section ~= '' then
            local row_start = row_num:match('%d+') or '1'
            anchor = string.format('#%s-%s', section, row_start)
        end
        text = string.format('%s\n* [[%s%s|查看日文原文]]', text, page, anchor)
    end

    return text
end

function p.main(frame)
    local args = tttools.normalize_args(frame:getParent().args)
    -- 追踪参数使用情况
    args = ArgsTracker(args)

    local text = p._main(args)
    local message = args:make_message{ template_name }

    if message then
        return text .. '\n<br />' .. message
    end
    return text
end

return p