模块:Dictionary/Vocabulary.lua:修订间差异

来自「荏苒之境」
无编辑摘要
无编辑摘要
(未显示同一用户的21个中间版本)
第1行: 第1行:
local csv = require("Module:Csv.lua")
local csv = require("Module:Csv.lua")
local dict_utils = require("Module:Dictionary-Utils.lua")
local dict_utils = require("Module:Dictionary/Utils.lua")
local dict_views = require("Module:Dictionary-Views.lua")
local dict_views = require("Module:Dictionary/Views.lua")


local html = mw.html
local html = mw.html
第7行: 第7行:


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


local vocabulary = {}
local vocabulary = {}


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


local function store_row(language, priority, row, extra_count)
local function query_existing_rows(language, rows)
     local r = cargo.query(DICT_TABLE, "Spelling,Definition,Extra", {
    local t = { "Language=\"", language, "\" AND Priority<>", tostring(DICT_HEADER_PRIORITY), " AND Spelling in (" }
         where = string.format(
    for i = 1, #rows do
            [[Language="%s" AND Spelling="%s" AND Priority>=%d]],
        t[#t+1] = "'"
            language, row[1], tonumber(priority))
        t[#t+1] = rows[i][1]
    })[1]
        t[#t+1] = "',"
    end
    t[#t] = "')"
     local query = cargo.query(DICT_TABLE, "Spelling,Definition,Extra,Priority,_pageName", {
         where = table.concat(t)
    })
    local found = {}
    for i = 1, #query do
        local raw = query[i]
        raw.Priority = tonumber(raw.Priority)
        found[raw.Spelling] = raw
    end
    return found
end


    if r and tonumber(r.Priority) > priority then
local function check_conflicting(prev_row, row, extra_count, on_conflict)
        local conflicting
    local compare_count = extra_count and extra_count + 2 or math.max(#row, #prev_row)
        local prev_row = dict_utils.expand_row(r, extra_count)
    local conflict = false
 
if on_conflict == nil then
        for i = 1, extra_count and extra_count+2 or math.max(#row, #prev_row) do
for i = 1, compare_count do
            if prev_row[i] ~= row[i] then
        local prev = prev_row[i]
                prev_row[i] = format_conflict(prev_row[i], row[i])
        local curr = row[i]
                conflicting = true
        if prev ~= curr then
            end
        return true
        end
        end
 
    end
        return conflicting and prev_row or nil
else
    end
    for i = 1, compare_count do
        local prev = prev_row[i]
        local curr = row[i]
        if prev ~= curr then
            on_conflict(i, prev_row, row)
            conflict = true
        end
    end
end
    return conflict
end


local function store_row(language, priority, row, extra_count)
     local extra = {}
     local extra = {}
     for i = 1, extra_count or #row-2 do
     for i = 1, extra_count or #row-2 do
         extra[i] = row[i+2]
         extra[i] = row[i+2]
     end
     end
     cargo.store(DICT_TABLE, {
     cargo.store(DICT_TABLE, {
         Language = language,
         Language = language,
第51行: 第75行:
vocabulary.show = function(frame)
vocabulary.show = function(frame)
     local args = frame.args
     local args = frame.args
    local page_name = frame.args.page_name
     local language = args.language
     local language = args.language
     local format = args.format
     local format = args.format
     local priority = args.priority
     local priority = tonumber(args.priority) or 1
     local content = args.content
     local content = args.content


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


    local header = rows.header
     local extra_count = #header - 2
     local extra_count = #header - 2
     local conflicting_header = store_row(language, -math.huge, header)
     local prev_header_raw = cargo.query(DICT_TABLE, "Spelling,Definition,Extra,_pageName", {
        where = "Language=\""..language.."\" AND Priority="..tostring(DICT_HEADER_PRIORITY)
    })[1]


     if conflicting_header then
     if prev_header_raw ~= nil and page_name ~= prev_header_raw._pageName then
         return html.create("pre")
         local prev_header = dict_utils.expand_row(prev_header_raw, extra_count)
            :css("color", "red")
        local is_conflicting = check_conflicting(prev_header, header, extra_count, format_conflict)
            :tag("p")
        if is_conflicting then
                :wikitext("检测到该词汇表的标题行(灰色文本)与之前储存的标题行冲突,请修复:")
            return html.create("pre")
                :done()
                :css("color", "red")
            :node(dict_views.vocabulary(conflicting_header, {}))
                :tag("p"):wikitext("检测到该词汇表的标题行(灰色文本)与之前储存的标题行文本冲突,请修复:"):done()
                :node(dict_views.vocabulary(prev_header, {}))
        end
    else
        store_row(language, DICT_HEADER_PRIORITY, header, extra_count)
     end
     end


    local existing_rows = query_existing_rows(language, rows)
     local conflicting_rows = {}
     local conflicting_rows = {}
      
      
     for i = 2, #rows do
     for i = 1, #rows do
         local conflicting_row = store_row(language, priority, rows[i], extra_count)
         local row = rows[i]
         if conflicting_row then
        local prev_row_raw = existing_rows[row[1]]
             conflicting_rows[i-1] = conflicting_row
        local prev_row = prev_row_raw and dict_utils.expand_row(prev_row_raw, extra_count)
         local ignore_store = false
 
        if prev_row_raw ~= nil then
            local prev_p = prev_row_raw.Priority
            if prev_p < priority then
                ignore_store = not check_conflicting(prev_row, row, extra_count)
            elseif prev_p > priority then
                ignore_store = true
             else
                ignore_store = check_conflicting(prev_row, row, extra_count, format_conflict)
                if ignore_store then
                    table.insert(conflicting_rows, prev_row)
                end
            end
        end
 
        if not ignore_store then
            store_row(language, priority, row, extra_count)
         end
         end
     end
     end

2025年8月5日 (二) 01:36的版本

此模块的文档可以在模块: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(i, prev_row, row)
    prev_row[i] = (prev_row[i] or "").."<br/><i style=\"color: grey\">"..(row[i] or "").."</i>"
end

local function query_existing_rows(language, rows)
    local t = { "Language=\"", language, "\" AND Priority<>", tostring(DICT_HEADER_PRIORITY), " AND Spelling in (" }
    for i = 1, #rows do
        t[#t+1] = "'"
        t[#t+1] = rows[i][1]
        t[#t+1] = "',"
    end
    t[#t] = "')"
    local query = cargo.query(DICT_TABLE, "Spelling,Definition,Extra,Priority,_pageName", {
        where = table.concat(t)
    })
    local found = {}
    for i = 1, #query do
        local raw = query[i]
        raw.Priority = tonumber(raw.Priority)
        found[raw.Spelling] = raw
    end
    return found
end

local function check_conflicting(prev_row, row, extra_count, on_conflict)
    local compare_count = extra_count and extra_count + 2 or math.max(#row, #prev_row)
    local conflict = false
	if on_conflict == nil then
		for i = 1, compare_count do
	        local prev = prev_row[i]
	        local curr = row[i]
	        if prev ~= curr then
	        	return true
	        end
	    end
	else
	    for i = 1, compare_count do
	        local prev = prev_row[i]
	        local curr = row[i]
	        if prev ~= curr then
	            on_conflict(i, prev_row, row)
	            conflict = true
	        end
	    end
	end
    return conflict
end

local function store_row(language, priority, row, extra_count)
    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 header
    local rows

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

    local extra_count = #header - 2
    local prev_header_raw = cargo.query(DICT_TABLE, "Spelling,Definition,Extra,_pageName", {
        where = "Language=\""..language.."\" AND Priority="..tostring(DICT_HEADER_PRIORITY)
    })[1]

    if prev_header_raw ~= nil and page_name ~= prev_header_raw._pageName then
        local prev_header = dict_utils.expand_row(prev_header_raw, extra_count)
        local is_conflicting = check_conflicting(prev_header, header, extra_count, format_conflict)
        if is_conflicting then
            return html.create("pre")
                :css("color", "red")
                :tag("p"):wikitext("检测到该词汇表的标题行(灰色文本)与之前储存的标题行文本冲突,请修复:"):done()
                :node(dict_views.vocabulary(prev_header, {}))
        end
    else
        store_row(language, DICT_HEADER_PRIORITY, header, extra_count)
    end

    local existing_rows = query_existing_rows(language, rows)
    local conflicting_rows = {}
    
    for i = 1, #rows do
        local row = rows[i]
        local prev_row_raw = existing_rows[row[1]]
        local prev_row = prev_row_raw and dict_utils.expand_row(prev_row_raw, extra_count)
        local ignore_store = false

        if prev_row_raw ~= nil then
            local prev_p = prev_row_raw.Priority
            if prev_p < priority then
                ignore_store = not check_conflicting(prev_row, row, extra_count)
            elseif prev_p > priority then
                ignore_store = true
            else
                ignore_store = check_conflicting(prev_row, row, extra_count, format_conflict)
                if ignore_store then
                    table.insert(conflicting_rows, prev_row)
                end
            end
        end

        if not ignore_store then
            store_row(language, priority, row, extra_count)
        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