跳转到内容

模組:Var/getVar

维基百科,自由的百科全书
local p = {}
local gsub = mw.ustring.gsub
local split = mw.ustring.split
local printf = mw.ustring.format
local trim = mw.text.trim
local messages = {
	magic_space = '\127'..string.char( 0xC2, 0xA0 ),
	strip_mark = "\127'\"`UNIQ--%s-%s-QINU`\"'\127"
};

function p._makeVar(frame, args, mode, from_meta_table)
	local varMode = mode or 'VAR'
	if varMode == 'NEW' then varMode = 'VAR' end
	if trim(varMode) == '' then varMode = 'VAR' end
    local out_text = function(out_mode,name,value)
    	return printf(messages.magic_space .. "$%s_DEF %s=%s" .. messages.magic_space, out_mode, name, value)
    end
    local body = ''
    local new_body = ''
    for key,val in pairs(args) do
    	local store_value = val
    	if from_meta_table == true then 
    		if type(store_value)~=type('string')then store_value="$JSON$".._jsonEncode(store_value)end 
    	end
    	if mode == 'DELETE' then body = body..out_text(varMode,store_value,store_value)..';'
    	else
    		if mode == 'NEW' then new_body = new_body..out_text('DELETE',key,key)..';' end
    		body = body..out_text(varMode,key,store_value)..';' 
    	end
    end
    if mode == 'NEW' then
    	new_body = frame:extensionTag('nowiki', new_body)
    end
    body = new_body .. frame:extensionTag('nowiki', body)
	return mw.text.tag( 'span', {style="display:none;"}, body )
end

function p._getVar(frame, args, to_get_mode, const, from_meta_table)
	to_get_mode = to_get_mode or 'value'
	local vars = p._getVars('VAR', const, frame)
    local var_name = args[1] or args['1'] or ''
    local get_value = vars[var_name] or (tonumber(var_name) and vars[tonumber(var_name)] or nil)
    if get_value then 
    	local get_result, check_json = gsub(get_value[to_get_mode], "^%$JSON%$", '')
    	if check_json > 0 and from_meta_table == true then
    		return mw.text.jsonDecode(get_result)
    	end
    	return get_result
    end
	return nil
end

function p._getVarHist(frame, args, from_meta_table)
    local vars = p._getVars('VAR', false, frame) 
    local var_name = args[1] or args['1'] or ''
    local get_value = vars[var_name] or (tonumber(var_name) and vars[tonumber(var_name)] or nil)
    if get_value then 
    	local formats = args[2] or args['2'] or'$'
    	local seps = args[3] or args['3'] or', '
    	local hists = split(get_value.hist,'$\127;\127^')
    	local body = ''
    	if from_meta_table == true then 
    		local get_result, check_json = {}, -1
    		for i=1, #hists do
    			get_result[i], check_json = gsub(hists[i], "^%$JSON%$", '')
		    	if check_json > 0 then
		    		get_result[i] = mw.text.jsonDecode(get_result[i])
		    	end
    		end
    		return get_result 
    	end
    	for i=1, #hists do
    		if i>1 then body = body .. seps end
    		body = body .. gsub(formats, '%$', hists[i])
    	end
    	return body
    end
    return nil
end

function p._getVars(VarMode, const, frame)
	frame = frame or mw.getCurrentFrame()
    local mark_get_mark, max_id = frame:extensionTag('nowiki', 'nowiki'), ''
	gsub(
		mark_get_mark,
		'nowiki%-([0-9A-Za-z]+)%-',
		function(id)
			max_id = id
		end
	)
	local max_id_num, body = tonumber(max_id, 16), ''
	local symbol_table = {}
	for i = 1, max_id_num do
		local try_get = mw.text.unstripNoWiki(p._stripMark('nowiki', string.format("%08X", i-1)))
		local in_index = 1
		gsub(
			try_get,
			messages.magic_space .. "%$([A-Z]+)_DEF%s+([^=]+)=([^" .. messages.magic_space .. ']*)', 
			function(sub_mode, f_key, f_value)--VarMode
				local key, value = f_key, f_value
				key = trim(key)
				if key ~= '' then
					local it if const == true then it = symbol_table[key] end
					local old = symbol_table[key]
					if sub_mode == 'DELETE' then
						symbol_table[key] = nil
					elseif sub_mode == VarMode then
						symbol_table[key] = it or {
							name=key,
							value=value,
							hist=((old or {}).hist and ( (old or {}).hist .. '$\127;\127^' ) or '') .. value,
							addr=string.format("%d:%d", (i-1), in_index)
						}
					end
				end
				in_index = in_index + 1
			end
		)
	end
	return symbol_table
end

function p._stripMark(mark_name, mark_id)
	return printf(messages.strip_mark, mark_name, mark_id)
end

return p