模块:Dictionary-Vocabulary.lua

来自「荏苒之境」

此模块的文档可以在模块:Dictionary-Vocabulary.lua/doc创建

local csv = require("Module:Csv.lua")
local dict_utils = require("Module:Dictionary-Utils.lua")
local dict_views = require("Module:Dictionary-Views.lua")

local html = mw.html
local cargo = mw.ext.cargo

local DICT_TABLE = dict_views.TABLE
local DICT_HEADER_PRIORITY = dict_utils.HEADER_PRIORITY

local vocabulary = {}

local function format_conflict(prev_value, curr_value)
    return (prev_value or "").."<br/><i style=\"color: grey\">"..(curr_value or "").."</i>"
end

local function store_row(page_name, language, priority, row, extra_count)
    local r = cargo.query(DICT_TABLE, "Spelling,Definition,Extra,Priority,_pageName", {
        where = string.format(
            [[Language="%s" AND Spelling="%s" AND Priority>=%d]],
            language, row[1], priority)
    })[1]

    if r then
    	if tonumber(r.Priority) > priority then
    		return
    	end
    	
    	local prev_row = dict_utils.expand_row(r, extra_count)
    	local compare_count = extra_count and extra_count+2 or math.max(#row, #prev_row)

    	if page_name == r._pageName then
    		local nochange = true
    		for i = 1, compare_count do
	            if prev_row[i] ~= row[i] then
	            	nochange = false
	                break
	            end
    		end
        	if nochange then return end
    	else
	        local conflicting
	        for i = 1, compare_count do
	            if prev_row[i] ~= row[i] then
	                prev_row[i] = format_conflict(prev_row[i], row[i])
	                conflicting = true
	            end
	        end
	        return conflicting and prev_row or nil
	    end
    end

    local extra = {}
    for i = 1, extra_count or #row-2 do
        extra[i] = row[i+2]
    end

    cargo.store(DICT_TABLE, {
        Language = language,
        Spelling = row[1],
        Definition = row[2],
        Extra = csv.format_row(extra),
        Priority = priority
    })
end

vocabulary.show = function(frame)
    local args = frame.args
    local page_name = frame.args.page_name
    local language = args.language
    local format = args.format
    local priority = tonumber(args.priority) or 1
    local content = args.content

    local rows
    if format == "csv" then
        rows = csv.parse(content, true)
    else
        mw.addWarning("无效的词典格式:"..tostring(format))
        return
    end

    local header = rows.header
    local extra_count = #header - 2
    local conflicting_header = store_row(page_name, language, DICT_HEADER_PRIORITY, header)

    if conflicting_header then
        return html.create("pre")
            :css("color", "red")
            :tag("p")
                :wikitext("检测到该词汇表的标题行(灰色文本)与之前储存的标题行文本冲突,请修复:")
                :done()
            :node(dict_views.vocabulary(conflicting_header, {}))
    end

    local conflicting_rows = {}
    
    for i = 2, #rows do
        local conflicting_row = store_row(page_name, language, priority, rows[i], extra_count)
        if conflicting_row then
        	table.insert(conflicting_rows, conflicting_row)
        end
    end

    local view = html.create("div")
    if #conflicting_rows ~= 0 then
        view:tag("pre")
            :css("color", "red")
            :tag("p")
                :wikitext("检测到旧词汇与新词汇(灰色文本)内容冲突的情况,且二者具有相同优先级,请统一词汇信息:")
                :done()
            :node(dict_views.vocabulary(header, conflicting_rows))
    end
    if frame.args.show_view == "true" then
        view:node(dict_views.vocabulary(header, rows))
    end
    return view
end

return vocabulary