Module:例句

维基教科书,自由的教学读本

本模塊被模板:例句使用。


-- TODO:
---- 維基詞典的鏈接
---- 省略後自動補充

--------------------
-- 導入模塊
--------------------
local getArgs = require('Module:Arguments').getArgs

local export = {}

--------------------
-- 常數定義
--------------------
local HTML_SPAN_LANG_FORMAT = "<span lang=\"%s\">%s</span>"
local CUSTOM_ROWS_AMOUNT = 5

local function split_string(str)
    local text = {}
    if str:sub(-1) ~= "%" then
        str = str .. "%"
    end
    for word in string.gmatch(str, "[^%%]*%%") do
        table.insert(text, word:sub(1, -2))
    end
    return text
end

local word_count = 0

--------------------
-- 生成對應行
--------------------
local function generate_tabularrow(str, caption, lang, colours, caption_on, style)
    local text = {}
    table.insert(text, '<tr>')
    local words = split_string(str)
    word_count = #words
    if caption_on then
        if caption then
            table.insert(text, '<th>' .. caption .. '</th>')
        else
            table.insert(text, '<th></th>')
        end
    end
    for index, word in pairs(words) do
        if caption == '變化' then
            word = '<span lang="en"><i>' .. word .. '</i></span>'
        end
        if caption == '原形' then
            word = '<span lang="' .. lang .. '"><i>' .. word .. '</i></span>'
        end

        local colour_definition = ''
        if colours and colours[index] then
            colour_definition = 'color: ' .. colours[index]
        end

        local border_definition = ''
        if index == 1 then
            -- 開頭
            border_definition = 'border-right: 1px solid #ccc'
        elseif index == word_count then
            -- 末尾
            border_definition = 'border-left: 1px solid #ccc'
        else
            -- 中間
            border_definition = 'border-left: 1px solid #ccc; border-right: 1px solid #ccc'
        end

        table.insert(text, ('<td class="example_sentence-word" style="padding: 0 3px;%s;%s;%s;">%s</td>'):format(colour_definition, border_definition, style or "", word))
    end
    table.insert(text, '</tr>')
    return table.concat(text)
end


--------------------
-- 生成自由行
--------------------
local function generate_freerow(caption, word_count, content, lang, style)
    if lang then
        content = HTML_SPAN_LANG_FORMAT:format(lang, content)
    end

    if caption then
        return ('<tr><th style="padding-right: 0.4em;">%s</th><td colspan="%d" style="%s">%s</td></tr>'):format(caption, word_count, style or "", content)
    else
        return ('<tr><td colspan="%d" style="%s">%s</td></tr>'):format(word_count, style or "", content)
    end
end

--------------------
-- 導出函數
--------------------
-- 參數列表:
---- 必須 lang              語言代碼,用於填入 <span> 的 lang 屬性
---- 必須 original_text     例文原文
---- 可選 translation       原文翻譯
---- 可選 word_dictionary   詞語原形
---- 可選 word_explanation  詞語解釋
---- 可選 inflection        詞語變化
function export.show(frame)
    -- 獲得實參
    local args = getArgs(frame)

    local lang = args[1] or args["語言"] or args['lang']
    local original_text = args[2] or args["原文"] or args['original_text'] or args['ot']
    local translation = args[3] or args["翻譯"] or args['translation'] or args['tr']
    local word_dictionary = args[4] or args["原形"] or args['dictionary'] or args['dc']
    local word_explanation = args[5] or args["解釋"] or args['explanation'] or args['ex']
    local word_inflection = args[6] or args["變化"] or args['inflection'] or args['inflexion'] or args['fl']
    local word_colour = args[7] or args["配色"] or args['colour'] or args['color'] or args['cl']

    local style_dictionary = args["原形樣式"]
    local style_explanation = args["解釋樣式"]
    local style_inflection = args["變化樣式"]

    local caption_custom_freerows = {}
    local custom_freerows = {}
    local style_custom_freerows = {}
    local position_custom_freerows = {}
    local lang_custom_freerows = {}
    local caption_custom_tabularrows = {}
    local custom_tabularrows = {}
    local style_custom_tabularrows = {}
    local position_custom_tabularrows = {}
    local lang_custom_tabularrows = {}
    for i = 1, CUSTOM_ROWS_AMOUNT do
        table.insert(caption_custom_freerows, args["fr" .. i .. "c"])
        table.insert(custom_freerows, args["fr" .. i])
        table.insert(style_custom_freerows, args["fr" .. i .. "s"])
        table.insert(position_custom_freerows, args["fr" .. i .. "p"])
        table.insert(lang_custom_freerows, args["fr" .. i .. "l"])
        table.insert(caption_custom_tabularrows, args["tr" .. i .. "c"])
        table.insert(custom_tabularrows, args["tr" .. i])
        table.insert(style_custom_tabularrows, args["tr" .. i .. "s"])
        table.insert(position_custom_tabularrows, args["tr" .. i .. "p"])
        table.insert(lang_custom_tabularrows, args["tr" .. i .. "l"])
    end

    local caption_on = true
    if args["隱藏標題"] and (args["隱藏標題"] == "true" or "真") then
        caption_on = false
    end

    ---- 配色
    local colours
    if word_colour then
        colours = split_string(word_colour)
    end

    -- 生成各行
    local text_orginal
    local text_dictionary
    local text_explanation
    local text_inflection
    local text_translation

    ---- 原形
    if word_dictionary then
        text_dictionary = generate_tabularrow(word_dictionary, '原形', lang, colours, caption_on, style_dictionary)
    end
    
    ---- 解釋
    if word_explanation then
        text_explanation = generate_tabularrow(word_explanation, '解釋', lang, colours, caption_on, style_explanation)
    end

    ---- 變化
    if word_inflection then
        text_inflection = generate_tabularrow(word_inflection, '變化', lang, colours, caption_on, style_inflection)
    end

    local text_custom_tabularrows = {}
    for i = 1, CUSTOM_ROWS_AMOUNT do
        if custom_tabularrows[i] then
            table.insert(text_custom_tabularrows, i, generate_tabularrow(custom_tabularrows[i], (caption_on and caption_custom_tabularrows[i] or nil), (lang_custom_tabularrows[i] or lang), colours, caption_on, style_custom_tabularrows[i]))
        end
    end

    if word_count == 0 then
        word_count = 1
    end

    ---- 原文
    if original_text then
        text_orginal = generate_freerow((caption_on and "原文" or false), word_count, original_text, lang, nil)
    end

    ---- 翻譯
    if translation then
        text_translation = generate_freerow((caption_on and "翻譯" or false), word_count, translation, nil, nil)
    end

    local text_custom_freerows = {}
    for i = 1, CUSTOM_ROWS_AMOUNT do
        if custom_freerows[i] then
            table.insert(text_custom_freerows, i, generate_freerow((caption_on and caption_custom_freerows[i] or false), word_count, custom_freerows[i], (lang_custom_tabularrows[i] or lang), style_custom_freerows[i]))
        end
    end

    -- TODO: 維護一個隊列,先排序,然後往裏面塞

    -- 

    local auto_rows = {}

    -- 開始:按序插入 --
    local rows = {}
    ---- 原文
    if text_orginal then
        table.insert(auto_rows, text_orginal)
    end
    ---- 原形
    if text_dictionary then
        table.insert(auto_rows, text_dictionary)
    end
    ---- 解釋
    if text_explanation then
        table.insert(auto_rows, text_explanation)
    end
    ---- 變化
    if text_inflection then
        table.insert(auto_rows, text_inflection)
    end
    ---- 翻譯
    if text_translation then
        table.insert(auto_rows, text_translation)
    end
    ---- 自定義
    for i = 1, CUSTOM_ROWS_AMOUNT do
        if custom_freerows[i] then
            if position_custom_freerows[i] then
                local index = tonumber(position_custom_freerows[i])
                if rows[index] then
                    error("重複的序號:" .. index)
                end
                table.insert(rows, index, text_custom_freerows[i])
            else
                table.insert(auto_rows, text_custom_freerows[i])
            end
        end

        if custom_tabularrows[i] then
            if position_custom_tabularrows[i] then
                local index = tonumber(position_custom_tabularrows[i])
                if rows[index] then
                    error("重複的序號:" .. index)
                end
                table.insert(rows, index, text_custom_tabularrows[i])
            else
                table.insert(auto_rows, text_custom_tabularrows[i])
            end
        end
    end
    -- 結束:按序插入 --

    -- 插入 auto_rows --
    local safe_rows = {}
    local j = 1
    -- TODO: 循環時 
    for i = 1, (CUSTOM_ROWS_AMOUNT * 2 + #auto_rows) do
        if rows[i] then
            table.insert(safe_rows, rows[i])
        else
            if auto_rows[j] then
                table.insert(safe_rows, auto_rows[j])
                j = j + 1
            end
        end
    end
    for i = j, #auto_rows do
        table.insert(safe_rows, auto_rows[i])
    end

    -- 輸出結果
    return '<table style="border-collapse: collapse; margin: 0.5em 0;">' .. table.concat(safe_rows) .. '</table>'
end

return export