模块:沙盒/a2569875/BluedeckLibraryTemplate

local p = {}
local lib_arg = {}
local lib_va = require("Module:Va")

local function getTitle(title)
	mw.log(title)
	local success_call, template_obj = pcall(mw.title.new, title, "Template")
	if not success_call then return nil end
	if not template_obj then return nil end
	success_call, template_obj = pcall(mw.title.new, lib_va.redirect_target(template_obj.fullText))
	if not success_call then return nil end
	if not template_obj then return nil end
	return template_obj
end
local depth = 0
function p.build_template(frame)
	depth = depth + 1
	local args, working_frame
	local inner_args
	--參數和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})
        inner_args = frame.args
        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
        inner_args = args
    end
    
	local template_name = args["@&$$~~!_template_name_!~~$$&@"] or 'void'
	local template_obj = getTitle(template_name)
	if template_obj and not template_obj.exists then
		local blib_obj = getTitle("User:Bluedecklibrary/"..template_obj.fullText)
		if blib_obj.exists then
			local success_call, template_body = xpcall(function()return blib_obj:getContent()end,function(err)return err end)
			if success_call and mw.text.trim(template_body or "") ~= "" then
				template_body = mw.ustring.gsub(template_body, "%{%{%s*user%s*:%s*bluedeck%s*/%s*infr%s*/%s*library%.card","{{void|")
			
				--關於noinclude、includeonly和onlyinclude的regexp
				local re_noinclude_head = "<%s*[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]%s*>"
				local re_noinclude_tail = "<%s*/%s*[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]%s*>"
				local re_noinclude = "<%s*/?%s*[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]%s*/?%s*>"
				local re_includeonly = "<%s*/?%s*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][Oo][Nn][Ll][Yy]%s*/?%s*>"
				local re_onlyinclude = "<%s*/?%s*[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]%s*/?%s*>"
				local re_removes = {{"noinclude",re_noinclude}, {"includeonly",re_includeonly}, {"onlyinclude",re_onlyinclude}}
				--摘除模板樣板中的noinclude與當中的內容
				local noinclude, _i = mw.ustring.find(template_body, re_noinclude_head), 1
				while noinclude do --如果找到<noinclude>
					--尋找</noinclude>
					local _, noinclude_end = mw.ustring.find(template_body, re_noinclude_tail)
					--如無</noinclude>,視為noinclude到頁面結尾
					noinclude_end = noinclude_end or -1
					--去除掉<noinclude>...</noinclude>與其之間的內容
					template_body = mw.ustring.sub(template_body, 1, noinclude-1) .. ((noinclude_end < 0) and "" or mw.ustring.sub(template_body, noinclude_end + 1, -1))
					--尋找下一個<noinclude>
					noinclude = mw.ustring.find(template_body, re_noinclude_head)
					_i = _i + 1 --避免無窮迴圈
					if _i > 100 then mw.addWarning(module_warn..'<noinclude>過多') break end
				end --<noinclude></noinclude>內容移除完畢
				--移除其他會影響解析功能的標籤
				for _, to_remove in pairs(re_removes) do _i = 1
					--處理巢狀引用
					local remove_count = 1 --紀錄移除數量
					while (tonumber(remove_count) or 0) > 0 do --如果還有殘留的相關標籤
						--移除殘留的相關標籤,並記錄移除數量
						template_body, remove_count = mw.ustring.gsub(template_body, to_remove[2], "")
						_i = _i + 1 --避免無窮迴圈
						if _i > 100 then mw.addWarning(module_warn..'<'..to_remove[1]..'>過多') break end
					end --如果沒有殘留的相關標籤則結束迴圈
				end
				template_body = mw.ustring.gsub(template_body, "%{%{%s*user%s*:%s*bluedeck%s*/%s*infr%s*/%s*library%.card","{{void|")
				template_body = mw.ustring.gsub(template_body, "%{%{%(%(%}%}","{{")
				template_body = mw.ustring.gsub(template_body, "%[%[:?(分[類类]):","[[%1:")
				template_body = mw.ustring.gsub(template_body, "%[%[:?([Cc][Aa][Tt]):","[[%1:")
				template_body = mw.ustring.gsub(template_body, "%[%[:?([Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]):","[[%1:")
				local child_frame = working_frame:newChild{ title = template_obj.fullText, args = args }
				blib_result = child_frame:preprocess(template_body)
				local target = nil
				mw.ustring.gsub(blib_result, "^[%s\n\r]*#[^%[%]]+%[%[([^%[%]]+)%]%]", function(str) target = str end)
				if type(target) ~= type(nil) then
					if depth > 10 then return blib_result end
					return p.build_template({["@%&$$~~!_template_name_!~~$$&%@"]=target})
				end
				return blib_result
			end
		end
	end
	return working_frame:expandTemplate{ title = ':'..template_obj.fullText, args = args }
end
return p