Module:Var

local p={}
local lib_arg={}
local lib_str=mw.ustring
local yesno = require('Module:Yesno')
local main_template_name = "Variable"
local module_call ="#invoke:Var"
local soft_subst_main = "Softsubst"
local messages,_L,lib_es,lib_tc,command_list = {
	magic_space = '\127'..string.char( 0xC2, 0xA0 ),
	strip_mark = "\127'\"`UNIQ--%s-%s-QINU`\"'\127",
	strip_mark_pattern = "\127'\"`UNIQ%%-%%-%s%%-%s%%-QINU`\"'\127",
	arg_global = '_arg_process',
	cant_subst = 'Variables cannot be accessed during the substitution phase.',
	cat_subst_not_done = "Pages with unresolved replacement references",
	not_support_strip_warning_cmt = "<!--可能需要手動調整的擴展標籤-->",
	not_support_strip_warning = "[[Template:softsubst]]警告:欲顯示替換引用原碼的模板中包含了擴展標籤,可能導致結果不準確,或替換引用失敗。",
	do_subst = '<p class="notice metadata" id="spoiler" style="font-size: small">以下内容為[[WP:Subst|替換引用]]後的預期內容,請自行拷貝原始碼完成替換引用。</p><div style="clear: both; overflow: auto; border: 1px solid #cccccc; padding: 4px; text-align: left; background: transparency;">',
	remove_hide_strip_mark = "<span%s+style%s*=%s*[\"\']%s*display%s*:%s*none%s*;?%s*[\"\']%s*>[^<]+UNIQ%-%-nowiki[^<]+<%s*/%s*span%s*>",
	var_undefine = '變數 "%s" 未定義。',
	NullPointerException = '[[NullPointerException|空指標]]錯誤'},{p=p},require("Module:EditState"),
	require("Module:TrackingCategory"),{'none',
	set = {'set', '設定', '設置'},
	get = {'get', '取值','取', '取得'},
	getconst = {'getconst'},
	ref = {'ref', '取址'},
	refget = {'refget', 'refgetname'},
	hide = {'hide', '隱藏'},
	subst = {'subst'},
	call = {'call', 'callconst', '呼叫', '執行', '運行'},
	hist = {'hist', '歷史'},
	delete = {'del', 'delete', '刪除'},
	new = {'new'},
};
local notsupport_strip = false
local no_color = false
local printf = lib_str.format
local sub = lib_str.sub
local gsub = lib_str.gsub
local trim = mw.text.trim
local split = mw.text.split
local function _test_cmd(cmd_names, test)
	local result, trim_test = false, trim(lib_str.lower(test))
	for i=1,#cmd_names do result = result or (trim_test == cmd_names[i]) end
	return result
end
local function addWarning(msg)
	return mw.addWarning(require('Module:Error').error{[1] = msg})
end
local function codeNowikiWithColor(frame, code_lang, text)
	if no_color then return frame:extensionTag('nowiki',text) end
	return frame:extensionTag('syntaxhighlight',text, {inline='', lang=code_lang})
end
local strip_code_color_map = {}
local ignore_strip_code = {
	indicator = true, 
	h=true,
	item=true
}
local function strip_code_color(frame, strip_code)
	local strip_type = strip_code:lower()
	if ignore_strip_code[strip_type] == true then return {'',''} end
	if no_color then return {messages.not_support_strip_warning_cmt .. '<' .. strip_type .. '>', '</' .. strip_type .. '>'} end
	local result = strip_code_color_map[strip_type]
	if result then return result else
		strip_code_color_map[strip_type] = {
			codeNowikiWithColor(frame, 'xml', messages.not_support_strip_warning_cmt .. '<' .. strip_type .. '>'),
			codeNowikiWithColor(frame, 'xml', '</' .. strip_type .. '>')
		}
	end
	return strip_code_color_map[strip_type]
end
local function no_color_check(frame, text)
	if no_color then return frame:extensionTag('pre',text) end
	return text
end
local function out_new_line()
	if no_color then return '\n' end
	return tostring(mw.html.create( 'br' ))
end
local subst_pattern = "%s*[Ss][Uu][Bb][Ss][Tt]%s*:%s*"
local safesubst_pattern = "%s*[Ss][Aa][Ff][Ee][Ss][Uu][Bb][Ss][Tt]%s*:%s*"
local msg_pattern = "%s*[Mm][Ss][Gg]%s*:%s*"
local msgnw_pattern = "%s*[Mm][Ss][Gg][Nn][Ww]%s*:%s*"
--區域變數結尾
local _jsonEncode =require('Module:EncoderUtil')._jsonEncode

--函數本體
function p.Varfunc(frame, from_meta_table)
	local args, working_frame = p._arg_process(frame)
	if mw.isSubsting() then return 
		require('Module:Template invocation').invocation(string.format("%s|%s",module_call,'softSubst_msg'), args)
	end
	local command = args['1'] or args[1] or ''
	if _test_cmd(command_list.set, command) or _test_cmd(command_list.new, command) or _test_cmd(command_list.delete, command) then
		local m_mode = 'VAR'
		if _test_cmd(command_list.delete, command) then m_mode = 'DELETE' 
		elseif _test_cmd(command_list.new, command) then m_mode = 'NEW' end
	   	local call_args = {}
	    for key,val in pairs(args) do
	    	local checker = tonumber(key)
	    	if checker ~= 1 then call_args[key] = val end
	    end
	    return p.makeVar(call_args, m_mode, from_meta_table)
	elseif _test_cmd(command_list.get, command) then
	   	return p.getVar({args['2'] or args[2] or '', args['3'] or args[3],default=args.default}, 'value', false ,from_meta_table)
	elseif _test_cmd(command_list.ref, command) then
	   	return p.getVar({args['2'] or args[2] or ''}, 'addr', false ,from_meta_table)
	elseif _test_cmd(command_list.getconst, command) then
	   	return p.getVar({args['2'] or args[2] or ''}, 'value', true, from_meta_table)
	elseif _test_cmd(command_list.refget, command) then
	   	local addr = args['2'] or args[2] or ''
	   	local result = p._getRefVarObj('VAR', addr)
	   	local remappingTable = {refget = 'value', refgetname = 'name'}
	   	if result then
	   		if result[remappingTable[command]] then return result[remappingTable[command]] end
	   	end
	   	return mw.getCurrentFrame():expandTemplate{ title = 'Error', args = { messages.NullPointerException } }
	elseif _test_cmd(command_list.hide, command) then
	   	if trim(args['2'] or args[2] or '')~= '' then
			working_frame:extensionTag('ref', args['2'] or args[2] or '', {group = 'UINQ-VARDEF-BLOCK-QINU'})
			working_frame:extensionTag('references', '', {group = 'UINQ-VARDEF-BLOCK-QINU'})
		end
	   	return ''
	elseif _test_cmd(command_list.subst, command) then
	   	return p._softSubst({args['2'] or args[2] or ''})
	elseif _test_cmd(command_list.call, command) then
	    return p.callVar(p._seek_arg(args, 1), command == 'callconst')
	elseif _test_cmd(command_list.hist, command) then
	    return p.getVarHist(p._seek_arg(args, 1), from_meta_table)
	end
	return ''
end

p.Var={
	set=function(i)local j=p._seek_arg(i,-1,true);for k,l in pairs(i)do j[k]=j[k]or l end j[1]='set';return p.Varfunc(j,true)end,
	new=function(i)local j=p._seek_arg(i,-1,true);for k,l in pairs(i)do j[k]=j[k]or l end j[1]='new';return p.Varfunc(j,true)end,
	delete=function(i)local j=p._seek_arg(i,-1,true);for k,l in pairs(i)do j[k]=j[k]or l end j[1]='delete';return p.Varfunc(j,true)end,
	get=function(i)local j=p._seek_arg(i,-1,true);j[1]='get';return p.Varfunc(j,true)end,
	getconst=function(i)local j=p._seek_arg(i,-1,true);j[1]='getconst';return p.Varfunc(j,true)end,
	hist=function(i)local j=p._seek_arg(i,-1,true);j[1]='hist';return p.Varfunc(j,true)end,
	call=function(i)local j=p._seek_arg(i,-1,true);j[1]='call';return p.Varfunc(j,true)end,
	refget=function(i)local j=p._seek_arg(i,-1,true);j[1]='refget';return p.Varfunc(j,true)end,
	refgetname=function(i)local j=p._seek_arg(i,-1,true);j[1]='refgetname';return p.Varfunc(j,true)end,
	ref=function(i)local j=p._seek_arg(i,-1,true);j[1]='ref';return p.Varfunc(j,true)end,
	vars=function(const)
		local arg_table = p._getVars("VAR", const)
		local restlt = {}
		for key,val in pairs(arg_table) do
			local get_result, check_json = mw.ustring.gsub(arg_table[key].value, "^%$JSON%$", '')
	    	if check_json > 0 then
	    		restlt[key] = mw.text.jsonDecode(get_result)
	    	else
	    		restlt[key] = get_result
	    	end
		end
		return restlt
	end
}

p.Var=setmetatable(p.Var, {
	__index = function(t, k) return t.get({k})end,
	__newindex = function(t, k, v)
		local stored = t.set({[k]=v})
		p.Varfunc({'hide',stored})
	end
})

function p.makeVar(frame, mode, from_meta_table)
	local varMode = mode or 'VAR'
	if varMode == 'NEW' then varMode = 'VAR' end
	if trim(varMode) == '' then varMode = 'VAR' end
	local args, working_frame = p._arg_process(frame)
    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 = working_frame:extensionTag('nowiki', new_body) end
    body = new_body .. working_frame:extensionTag('nowiki', body)
	return mw.text.tag( 'span', {style="display:none;"}, body )
end

function p.softSubst(frame)
	local args, working_frame = p._arg_process(frame)
	if mw.isSubsting() then return require('Module:Template invocation').invocation(soft_subst_main, args)end
	local template_title = trim(args['1'] or args['1'] or '')
	if template_title == '' then return '' end
	return p.softSubst_msg(p._seek_arg(args, 1), template_title,
		yesno(args['no cat']or args['no_cat']or args.nocat or args.NoCat or args.noCat or false))
end
local function check_is_main_doc(working_frame)
	local checker = mw.ustring.lower(working_frame:preprocess( "{{BASEPAGENAME}}" ))
	if	checker == mw.ustring.lower(main_template_name) or 
		checker == mw.ustring.lower(soft_subst_main) or checker == 'var' then return true end
    return false
end
function p.softSubst_msg(frame, template_title, without_cat)
	local template_dis = template_title or main_template_name
	local args, working_frame = p._arg_process(frame)
	if mw.isSubsting() then return require('Module:Template invocation').invocation(string.format("%s|%s",module_call,'softSubst_msg'), args)end
	local result = require('Module:Template invocation').invocation(template_dis, args)
	if lib_es.isPreview() then 
		local pre_result  = working_frame:preprocess(result)
		if #(split(gsub(pre_result,'\r\n','\n'),'\n')) > 50 then no_color = true end
		result = p._softSubst({working_frame:preprocess(result)})
		if template_title == nil then 
			result = working_frame:expandTemplate{ title = 'Error', args = { messages.cant_subst } } .. result
		end
		if notsupport_strip==true then result = '<p>{{Error|' .. messages.not_support_strip_warning .. '}}</p>' .. result end
	else
		if (check_is_main_doc(working_frame) == false) and (not without_cat) then lib_tc.append(messages.cat_subst_not_done) end
	end
	if notsupport_strip==true then addWarning( messages.not_support_strip_warning ) end
	return working_frame:preprocess(result)
end

function p._softSubst(frame)
	local softSubst_data, softSubst_warp = 'arg_global', string.char(0x70)
	if type(softSubst_data) ~= type({'table'}) then
		--find method between global scope or local scope
		softSubst_data = {(_G[softSubst_warp] or _L[softSubst_warp])[messages[softSubst_data]](frame)}
	end
	local without_cat = yesno(softSubst_data['no cat']or softSubst_data['no_cat']or softSubst_data['nocat']or softSubst_data['NoCat']or softSubst_data['noCat']or false)
	--decode method
	local first_data, second_data, third_data = softSubst_data['1'] or softSubst_data[1], softSubst_data['2'] or softSubst_data[2], (_G[softSubst_warp] or _L[softSubst_warp])["_code_getter_wiki"]
	--2nd layer decode
	first_data = first_data['1'] or first_data[1] or ''
	--second_data = second_data['2'] or second_data[2] or ''
	--third_data = third_data['3'] or third_data[3] or ''
	if lib_es.isPreview() ~= true and (not without_cat) then 
		if (check_is_main_doc(second_data) == false) then lib_tc.append(messages.cat_subst_not_done) end
	end
	local fourth_data = function(msg_data)
		local msg_data_list, result_code = split(msg_data, '\n'), ''
		for i=1,#msg_data_list do result_code = result_code .. third_data(second_data, msg_data_list[i]) end
		if no_color then result_code = no_color_check(second_data, result_code) end
		return result_code
	end
	--foreach method do
   	if trim(first_data)~= '' then return
   		mw.clone(messages.do_subst) .. fourth_data(gsub(
			gsub(first_data, messages.remove_hide_strip_mark, '')
		, '\r\n', '\n')) .. '</div>'
	end
   	return ''
end

function p.callVar(frame, const)
	local args, working_frame = p._arg_process(frame)
    local vars = p._getVars('VAR', const)
    local var_name = args[1]or args['1']or''
    local get_value = vars[var_name]
    if tonumber(var_name) and not get_value then get_value = vars[tonumber(var_name)] end
    if get_value then 
    	local func_name = trim(mw.clone(get_value.value),"|\t\r\n\f ")
    	func_name = gsub(func_name,subst_pattern,'')
    	func_name = gsub(func_name,safesubst_pattern,'')
    	func_name = gsub(func_name,msg_pattern,'')
    	func_name = gsub(func_name,msgnw_pattern,'')
    	
    	local tail_index = (lib_str.find(func_name,'|')or(lib_str.len(func_name)+1))-1
    	command_tail = sub(func_name,tail_index + 1,-1)
    	func_name = sub(func_name,1,tail_index)

    	local final_func_name = ''
    	
		--template:
		local template_name = mw.title.new( func_name, 'Template' )
		if template_name and template_name.exists then 
			final_func_name = template_name.fullText 
			if template_name.namespace == 0 then final_func_name = ':' .. final_func_name end
		end 

		--int:
		local template_split = split(func_name, ':') or {func_name}
		if final_func_name=='' then
			local check_mw = func_name
			if #template_split > 1 and (sub(template_split[1],1,3) == 'int' or 
					(lib_str.find(template_split[1],"[Mm]edia[Ww]iki"))) then
				check_mw = table.concat( template_split, ':', 2, #template_split )
			end
			if mw.message.new(check_mw):exists() then
				final_func_name = 'int:' .. check_mw
			end
		end

		--#...:
		local fix_cs = false
		if final_func_name=='' then
			if xpcall(function()mw.getCurrentFrame():callParserFunction( func_name, func_name )end, function()end) 
					== true then
				final_func_name = func_name
				fix_cs = true
				local parser_tail_check = sub(trim(final_func_name),-1)
				if parser_tail_check ~= ':' and parser_tail_check ~= '|' then final_func_name = final_func_name .. ':' end
			end
		end

		--may be magic word
		if final_func_name=='' then
			local checker, check_text = xpcall(function()
				return mw.getCurrentFrame():preprocess( printf("{{%s}}", func_name) )
			end, function()end)
			local test_name = (template_name or { prefixedText = func_name }).prefixedText
			if		not lib_str.find(check_text or '', printf("^{{%s}}$", test_name) ) and
					not lib_str.find(check_text or '', printf("^%%[%%[:%s%%]%%]$", test_name) ) then
				final_func_name = func_name
			end
		end

		if trim(final_func_name) ~= '' then
		    local num_args = p._seek_arg(args, 1)

			local str_args = require('Module:Template invocation').invocation(final_func_name..command_tail, num_args)
			if fix_cs == true and trim(command_tail) == '' and 
					sub(trim(final_func_name),-1) == ':' then 
				str_args = gsub(str_args, "^({{)%s*(" .. final_func_name .. ")|", "%1%2")
			end
			return working_frame:preprocess(str_args)
		end
		local max_arg = 0 
    	local num_args = {}
		for key,value in pairs( args ) do
			local arg_id = tonumber(key or '')
			if arg_id then
				if arg_id > max_arg then max_arg = arg_id end
				num_args[arg_id] = value
			end
		end
		local call_args = {}
		local get_obj = function(obj)return mw.text.jsonDecode(obj)end
		if max_arg > 1 then
			for i = 2,max_arg do
				if num_args[i] then 
					local try_to_get_obj = mw.clone(num_args[i])
					if not xpcall( function() --try
						try_to_get_obj = get_obj(num_args[i])
					end, function(msg)return msg end ) then --catch
						call_args[i-1] = num_args[i]
					else --finally
						call_args[i-1] = try_to_get_obj
					end
				else call_args[i-1] = '' end
			end
		end
		local func_path = split(func_name,'%.') or { [1]=func_name }
		local func_body = mw[func_path[1]] or p[func_path[1]] or _G[func_path[1]]
		if lib_str.find(func_path[1],':') then
			func_body = require(func_path[1]) or func_body
		end
		if func_body then
			local old_obj = func_body
			for i=2,#func_path do
				func_body = func_body[func_path[i]]
				if func_body then
					old_obj = func_body
				else
					return ''
				end
			end
			local func_type = type( func_body )
			local times = 10
			for ti = 1,times do
				if func_type == type(nil) then
					return ''
				elseif func_type == type(0) then
					return '' .. func_body
				elseif func_type == type(true) then
					if func_body then return '1' end
					return ''
				elseif func_type == type(type) then
					if max_arg > 1 then 
						func_body = func_body(unpack(call_args))
						if func_body == nil then func_body = call_args[1] end
					else func_body = func_body() end
				elseif func_type == type("string") then
					return func_body
				elseif func_type == type({}) then
					return _jsonEncode(func_body)
				end
				func_type = type( func_body )
			end
		end
		return func_name
    end
    if trim(var_name) ~= '' then
    	return working_frame:expandTemplate{ title = 'Error', args = { printf(messages.var_undefine, var_name) } }
    end
	return ''
end
function p._arg_process(frame)
	local args, working_frame
    if frame == mw.getCurrentFrame() then
        -- We're being called via #invoke. The args are passed through to the module
        -- from the template page, so use the args that were passed into the template.
        if lib_arg.getArgs == nil then lib_arg = require('Module:Arguments') end
        args = lib_arg.getArgs(frame, {
        	parentFirst=true,
        	trim = false,
			removeBlanks = false
        })
        working_frame = frame
    else
        -- We're being called from another module or from the debug console, so assume
        -- the args are passed in directly.
        args = frame
        working_frame = mw.getCurrentFrame()
        if type(args) ~= type({}) then args = {frame} end
    end
    return args, working_frame
end
function p.getVar(frame, get_mode, const, from_meta_table)
	local to_get_mode = get_mode or 'value'
	local args, working_frame = p._arg_process(frame)
	local vars = p._getVars('VAR', const)
    local var_name = args[1]or args['1']or''
    local get_value = vars[var_name]
    if tonumber(var_name) and not get_value then get_value = vars[tonumber(var_name)] end
    if get_value then 
    	local get_result, check_json = mw.ustring.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
    if trim(var_name) ~= '' then
    	if args[2]or args['2'] or args.default then return args[2]or args['2']or args.default end
    	if from_meta_table == true then return error(printf(messages.var_undefine, var_name)) end
    	return working_frame:expandTemplate{ title = 'Error', args = { printf(messages.var_undefine, var_name) } }
    end
	return ''
end

function p.getVarHist(frame, from_meta_table)
	local args, working_frame = p._arg_process(frame)
    local vars = p._getVars('VAR') 
    local var_name = args[1]or args['1']or''
    local get_value = vars[var_name]
    if tonumber(var_name) and not get_value then get_value = vars[tonumber(var_name)] end
    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 = mw.ustring.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
    if trim(var_name) ~= '' then
    	if from_meta_table == true then return error(printf(messages.var_undefine, var_name)) end
    	return working_frame:expandTemplate{ title = 'Error', args = { printf(messages.var_undefine, var_name) } }
    end
	return ''
end

function p._getRefVarObj(VarMode, addr)
	local addr_path = split(addr,':')
	if #addr_path == 2 then
		local strip_id, addr_loc = addr_path[1], addr_path[2]
		strip_id = tonumber(strip_id)
		addr_loc = tonumber(addr_loc)
		if strip_id and addr_loc then
			local try_get = mw.text.unstripNoWiki( p._stripMark('nowiki', string.format( "%08X", strip_id )) )
			local in_index, arg_data = 1, nil
			gsub(try_get, messages.magic_space .. "%$" .. VarMode .. "_DEF%s+([^=]+)=([^" .. messages.magic_space .. ']*)', 
			function(f_key, f_value)
				local key, value = f_key, f_value
				key = trim(key)
				if in_index == addr_loc then 
					arg_data = {
						name=key,
						value=value,
						addr=string.format( "%d:%d", strip_id, in_index )
					} end
				in_index = in_index + 1
			end)
			return arg_data
		end
	end
	return nil
end
function p._seek_arg(input_args_list, offset, enable_minus)
    local num_args = {}
    if enable_minus~=true and offset <= 1 then offset = 1 end
	for key,value in pairs(input_args_list) do
		local num = tonumber(key) or 0
		local stored = false
		if num then
			if num > offset then
				num_args[num - offset] = value
				stored = true
			end
			if num >= 1 and num <= offset then stored = true end
		end
		if stored ~= true then num_args[key] = value end
	end
	return num_args
end
function p._code_getter_wiki(working_frame, input_code)
	local current_text, code_lang = input_code, "moin"
	local flag1 = lib_str.find(current_text, "<%s*/?%s*[A-Za-z]")
	local flag2 = lib_str.find(current_text, "[A-Za-z\"']%s*/?%s*>")
	if flag1 or flag2 then code_lang = "html" end
	local body = ''
	local strip_to_remove = split(current_text,'\127')
	for i=1,#strip_to_remove do
		local current_strip = strip_to_remove[i]
		if lib_str.find(current_strip,"'\"`UNIQ%-%-") then
			if lib_str.find(current_strip, "nowiki") then 
				local try_unstrip = '\127' .. current_strip .. '\127'
				try_unstrip = mw.text.unstripNoWiki( try_unstrip )
				if lib_str.find(try_unstrip,"'\"`UNIQ%-%-") then
					--不存在的strip entity
					body = body .. '\127' .. current_strip .. '\127'
				else
					try_unstrip = mw.text.decode(try_unstrip)
					try_unstrip = printf("<nowiki>%s</nowiki>",table.concat( split(try_unstrip,"nowiki"),'</nowiki>nowiki<nowiki>'))
					body = body .. codeNowikiWithColor(working_frame, 'xml', try_unstrip)
				end
			else
				--保留原始strip符號令解析器自動替換
				local strip_type = ''
				gsub(current_strip, "UNIQ%-%-([%dA-Za-z]+)%-", function(in_str)strip_type=in_str end)
				local out_strip_text = '\127' .. current_strip .. '\127'
				if strip_type ~= '' then 
					local strip_code_color_data = strip_code_color(working_frame, strip_type)
					out_strip_text = strip_code_color_data[1] .. out_strip_text ..strip_code_color_data[2]
				end
				body = body .. out_strip_text
				notsupport_strip = true
			end
		elseif trim(current_strip) ~= '' then
			local avoid_t = split(current_strip, '%-{') or {avoid_t}
			for a_i = 1,#avoid_t do
				local a_ic = avoid_t[a_i]
				if a_i ~= 1 then a_ic = '{' .. a_ic end
				if a_i ~= #avoid_t then a_ic = a_ic .. '-' end
				body = body .. codeNowikiWithColor(working_frame, code_lang, a_ic)
			end
		end
	end
	return body .. out_new_line()
end

function p._getVars(VarMode, const)
	local frame = 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

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.