コンテンツにスキップ
X (Twitter)の淫夢語録Botで新しい語録と出会おう(提案)

利用者:InmuTroll/ruby

提供: 真夏の夜の淫夢Wiki

Lua使えないのか…(落胆)

-- using Wagner–Fischer algorithm
local function str_ucompare(s1, s2, limit)
    s1, s2 = mw.text.split(s1, ''), mw.text.split(s2, '')
    local len1, len2 = #s1, #s2
    if limit and len1 * len2 * 20 > limit then return {{s1}, {s2}} end

    local m_cost, m_step = {{0}}, {{}}
    for i = 1, len1 do
        m_cost[i + 1] = {i}
        m_step[i + 1] = {3}
    end
    for j = 1, len2 do
        m_cost[1][j + 1] = j
        m_step[1][j + 1] = 4
    end

    for i = 1, len1 do
        for j = 1, len2 do
            local b_same = s1[i] == s2[j]
            local c_sub = m_cost[i][j] + (b_same and 0 or 1)
            local c_del = m_cost[i][j + 1] + 1
            local c_ins = m_cost[i + 1][j] + 1
            if c_sub <= c_del and c_sub <= c_ins then
                m_cost[i + 1][j + 1] = c_sub
                m_step[i + 1][j + 1] = b_same and 1 or 2
            elseif c_del <= c_ins then
                m_cost[i + 1][j + 1] = c_del
                m_step[i + 1][j + 1] = 3
            else
                m_cost[i + 1][j + 1] = c_ins
                m_step[i + 1][j + 1] = 4
            end
        end
    end

    local i1, i2 = len1 + 1, len2 + 1
    local m_offset = {{-1, -1}, {-1, -1}, {-1, 0}, {0, -1}}
    local r_step_rev = {}
    local r_step_rev_pos1 = {}
    local r_step_rev_pos2 = {}
    local step = m_step[i1][i2]
    while step do
        table.insert(r_step_rev, step)
        i1 = i1 + m_offset[step][1]
        i2 = i2 + m_offset[step][2]
        table.insert(r_step_rev_pos1, i1)
        table.insert(r_step_rev_pos2, i2)
        step = m_step[i1][i2]
    end

    local r1, r2 = {}, {}
    local i = #r_step_rev
    local step = r_step_rev[i]
    while i > 0 do
        local r1_f, r2_f = {}, {}
        if step == 1 then
            repeat
                table.insert(r1_f, s1[r_step_rev_pos1[i]])
                table.insert(r2_f, s2[r_step_rev_pos2[i]])
                i = i - 1
                step = r_step_rev[i]
            until step ~= 1
        else
            while true do
                if step == 2 then
                    table.insert(r1_f, s1[r_step_rev_pos1[i]])
                    table.insert(r2_f, s2[r_step_rev_pos2[i]])
                elseif step == 3 then
                    table.insert(r1_f, s1[r_step_rev_pos1[i]])
                elseif step == 4 then
                    table.insert(r2_f, s2[r_step_rev_pos2[i]])
                else
                    break
                end
                i = i - 1
                step = r_step_rev[i]
            end
        end
        table.insert(r1, table.concat(r1_f))
        table.insert(r2, table.concat(r2_f))
    end
    return {r1, r2}
end

return {
   ruby = function(frame)
       local text_blocks = str_ucompare(frame.args[1], frame.args[2])
       local result = {}
       for index, text_below in ipairs(text_blocks[1]) do
           local text_above = text_blocks[2][index]
           if text_above == text_below then
               table.insert(result, text_below)
           else
               table.insert(result, '<ruby>' .. text_below .. '<rp>(</rp><rt>' .. text_above .. '</rt><rp>)</rp></ruby>')
           end
       end
       return table.concat(result)
   end,
}