local module = {} local getArgs = require('Module:Arguments').getArgs local pack_inner_loop = function(loop) -- 给内层循环的do参数包裹<nowiki>标签 loop = mw.ustring.gsub(loop, '{{%s-[lL][oO][oO][pP]%s-|', '{{#invoke:loop|main|') return mw.ustring.gsub(loop, '({{#invoke:loop.*)', function(a) local i = 1 local stack = {} local do_begin = -1 local do_end = -1 while (i < mw.ustring.len(a)) do if do_begin == -1 and mw.ustring.find(a, '^|%s-do%s-=', i) then _, do_begin = mw.ustring.find(a, '^|%s-do%s-=', i) do_begin = do_begin + 1 i = do_begin end if do_begin ~= -1 then if mw.ustring.sub(a, i, i + 2) == '{{{' then i = i + 3 table.insert(stack, 3) elseif mw.ustring.sub(a, i, i + 1) == '{{' then i = i + 2 table.insert(stack, 2) elseif mw.ustring.sub(a, i, i + 2) == '}}}' then if #stack ~= 0 and stack[#stack] == 3 then i = i + 3 table.remove(stack) elseif #stack ~= 0 and stack[#stack] == 2 then i = i + 2 table.remove(stack) else do_end = i - 1 break end elseif mw.ustring.sub(a, i, i + 1) == '}}' then if #stack ~= 0 then i = i + 2 table.remove(stack) else do_end = i - 1 break end elseif mw.ustring.sub(a, i, i) == '|' and #stack == 0 then do_end = i - 1 break else i = i + 1 end else i = i + 1 end end if do_begin ~= -1 and do_end == -1 then do_end = i - 1 end if do_begin ~= -1 and do_end ~= -1 then -- mw.log('发现内层循环 <nowiki>'..mw.ustring.sub(a, do_begin, do_end)..'</nowiki>') return mw.ustring.sub(a, 1, do_begin - 1)..'<nowiki>'.. mw.text.trim(mw.ustring.sub(a, do_begin, do_end))..'</nowiki>'.. pack_inner_loop(mw.ustring.sub(a, do_end + 1, -1)) else return a end end ) end local _main = function(args, frame, dowhile) --初步处理条件语句 local condition = args['condition'] or '' condition = mw.text.unstripNoWiki(condition) condition = string.gsub(condition, '<!%-%-.-%-%->', '') --修整条件语句的格式 local trim = mw.text.split(condition, '\n') condition = '' for i, v in ipairs(trim) do condition = condition..mw.text.trim(v) end condition = mw.text.decode(condition) -- mw.log('循环体= '..condition) --初步处理循环体 local loop = args['do'] or '' loop = mw.text.unstripNoWiki(loop) loop = string.gsub(loop, '<!%-%-.-%-%->', '') --处理循环体中的次级循环语句 loop = pack_inner_loop(loop) --修整循环体中语句的格式 local trim = mw.text.split(loop, '\n') loop = '' for i, v in ipairs(trim) do loop = loop..mw.text.trim(v) end loop = mw.text.decode(loop) -- mw.log('循环体= '..loop) local result = '' if dowhile then -- mw.log('执行循环体('..name..'='..tostring(i)..') '..loop) repeat result = result..frame:preprocess(loop) until frame:preprocess(condition) == '' else -- mw.log('执行循环体('..name..'='..tostring(i)..') '..loop) while frame:preprocess(condition) ~= '' do result = result..frame:preprocess(loop) end end -- mw.log('循环结果 '..result) return result end module["while"] = function(frame) if (frame:getParent() or frame):getTitle() == 'Template:While' and frame.args['do'] == nil then args = getArgs(frame) else args = frame.args end return _main(args, frame:getParent() or frame, false) end module.dowhile = function(frame) if (frame:getParent() or frame):getTitle() == 'Template:While' and frame.args['do'] == nil then args = getArgs(frame) else args = frame.args end return _main(args, frame:getParent() or frame, true) end return module