跳转到内容

模組:NoteTA-lite

被永久保护的模块
维基百科,自由的百科全书

这是本页的一个历史版本,由GnolizX留言 | 贡献2025年2月16日 (日) 17:40 (允许 {{#invoke:NoteTA-lite|main|xxx}} 写法)编辑。这可能和当前版本存在着巨大的差异。

local z = {}
local WikitextLC = require( 'Module:WikitextLC' )

function Tcode( args )
	if args.T == nil or args.T == '' then
		return ''
	end
	local div = mw.html.create( 'div' )
		:attr( 'class', 'noteTA-title' )
		:attr( 'data-noteta-code', args.T )
		:wikitext( WikitextLC.title( args.T ) )
	if args.dt ~= nil and args.dt ~= '' then
		div:attr( 'data-noteta-desc', args.dt )
	end
	return tostring( div )
end

function group( name, frame )
	if name == nil or name == '' then
		return ''
	end
	local moduleTitle = mw.title.makeTitle( 'Module', 'CGroup/' .. name )
	if moduleTitle and moduleTitle.exists then
		local data = mw.loadData( 'Module:CGroup/' .. name )
		local pieces = {}
		if data.content then
			local matched_indices = z.match_text_with_cgroup(mw.title.getCurrentTitle(), data.content)
			for i, v in ipairs( data.content ) do
				if matched_indices[i] and v.type == 'item' and v.rule then
					table.insert( pieces, '-{H|' .. v.rule .. '}-' )
				end
			end
			return tostring( mw.html.create( 'div' )
				:attr( 'data-noteta-group-source', 'module' )
				:attr( 'data-noteta-group', data.name or name )
				:wikitext( table.concat( pieces ) ) )
		end
	end
	local templateTitle = mw.title.makeTitle( 'Template', 'CGroup/' .. name )
	if templateTitle and templateTitle.exists then
		return frame:expandTemplate{ title = templateTitle }
	end
	return tostring( mw.html.create( 'div' )
			-- :attr( 'id', 'noteTA-group-' .. mw.uri.anchorEncode( name ) )
			:attr( 'data-noteta-group-source', 'none' )
			:attr( 'data-noteta-group', name ) )
end

function Gcode( args, frame )
	local code = {}
	for i = 1, 30 do
		table.insert( code, group( args['G' .. i], frame ) )
	end
	code = table.concat( code )
	if code ~= '' then
		code = tostring( mw.html.create( 'div' )
				:attr( 'class', 'noteTA-group' )
				:wikitext( code ) )
		if args.G31 ~= nil then
			code = code .. '[[Category:NoteTA模板参数使用数量超过限制的页面|G]]'
		end
	end
	return code
end

function local_( i, code, desc )
	if code == nil or code == '' then
		return ''
	end
	local div = mw.html.create( 'div' )
		-- :attr( 'id', 'noteTA-local-' .. i )
		:attr( 'data-noteta-code', code )
		:wikitext( WikitextLC.hidden( code ) )
	if desc ~= nil and desc ~= '' then
		div:attr( 'data-noteta-desc', desc )
	end
	return tostring( div )
end

function Lcode( args )
	local code = {}
	for i = 1, 30 do
		table.insert( code, local_( i, args[i], args['d' .. i] ) )
	end
	code = table.concat( code )
	if code ~= '' then
		code = tostring( mw.html.create( 'div' )
				:attr( 'class', 'noteTA-local' )
				:wikitext( code ) )
		if args[31] ~= nil then
			code = code .. '[[Category:NoteTA模板参数使用数量超过限制的页面|L]]'
		end
	end
	return code
end

function z.main( frame )
	local args
	if frame == mw.getCurrentFrame() then
		-- Being called from {{noteTA}}
		args = require('Module:Arguments').getArgs(frame)
	else
		-- Being called from another module
		args = frame
		frame = mw.getCurrentFrame()
	end
	local Tc = Tcode( args )
	local Gc = Gcode( args, frame )
	local Lc = Lcode( args )
	local code = Tc .. Gc .. Lc
	if code ~= '' then
		local hash = require( 'Module:Crc32lua' ).crc32( mw.dumpObject( args ) )
		code = frame:extensionTag{
			name = 'indicator',
			content = '[[File:Zh conversion icon m.svg|35px|本页使用了标题或全文手工转换|link=|class=skin-invert]]',
			args = { name = string.format( 'noteTA-%x', hash ) },
		} .. tostring( mw.html.create( 'div' )
				:attr( 'id', string.format( 'noteTA-%x', hash ) )
				:attr( 'class', 'noteTA' )
				:wikitext( code ) )
		if mw.title.getCurrentTitle():inNamespace( 'Template' ) then
			code = code .. '[[Category:放置于模板的noteTA]]'
		end
	end
	return code
end

--------------------------------------------------------------------------------

-- Construct a trie from CGroup rules for faster matching.
function z.build_trie(cgroup_content)
	local matchers = {}
	for index, content in ipairs(cgroup_content) do
		if content.type == 'item' then
			for full_rules in string.gmatch('-{H|' .. content.rule .. '}-', '%-{.-|(.-)}%-') do -- 可能会有多个 -{x|yyy}- 写在一个 rule 里面,获取每个 yyy
				for rules in string.gmatch(full_rules, '([^;]+)') do
					local matcher = rules:match("=>") and rules:match('^(.-)=>') or rules:match('^.-:(.+)') -- 按 ";" 分割后,有 "=>" 就取前面的,没有就取第一个 ":" 后面的
					if matcher then
						mather_trimmed = mw.text.trim(matcher)
						matchers[mather_trimmed] = matchers[mather_trimmed] or {}
						table.insert(matchers[mather_trimmed], index)
					end
				end
			end
		end
	end
	
	local trie = {}
	for matcher, index in pairs(matchers) do
		local current_node = trie
		for i = 1, #matcher do
    		local byte = matcher:sub(i,i)
			current_node[byte] = current_node[byte] or {}
			current_node = current_node[byte]
		end
		current_node.index = index
	end
	
	return trie
end

-- Match the content of an article against CGroup rules using a trie.
function z.match_text_with_cgroup(article_title, cgroup_content)
	local trie = z.build_trie(cgroup_content)
	local content = article_title:getContent()
	
	local matches = {}
    for start_pos = 1, #content do
        local current_node = trie
        local matched_index = nil
        for i = start_pos, #content do
            local byte = content:sub(i, i)
            current_node = current_node[byte]
            if not current_node then
                break
            end
            if current_node.index then
                matched_index = current_node.index
            end
        end
        
        if matched_index then
        	for i = 1, #matched_index do
        		matches[matched_index[i]] = true
        	end
        end
    end
    
    return matches
end

--------------------------------------------------------------------------------

return z