跳转到内容

模組:Loop

本页使用了标题或全文手工转换
维基百科,自由的百科全书

local p = {}
local mYesno
local mTemplateParameters
local libraryUtil = require('libraryUtil')

local function yesno(value)
	if not mYesno then
		mYesno = require('Module:Yesno')
	end
	return mYesno(value)
end
	
function p._loop(opt)
	libraryUtil.checkTypeForNamedArg('Module:Loop#_loop', 'loopWeight', opt.loopWeight, 'number', true)
	libraryUtil.checkTypeForNamedArg('Module:Loop#_loop', 'validateCondition', opt.validateCondition, 'function', true)
	libraryUtil.checkTypeForNamedArg('Module:Loop#_loop', 'stopCondition', opt.stopCondition, 'function', false)

	return function (frame)	
		local args = frame.args
		local loopStart = tonumber(args['start'])
		local loopEnd = tonumber(args['end'])
		local loopContent = args.content
		if loopStart == loopEnd or not loopContent then
			return ''
		end
		local loopRange = tonumber(args['range']) or 1
		if loopRange <= 0 then
			error('range must be a positive number.')
		end
		if (opt.loopWeight or 1) < 0 and (loopStart < loopEnd) or (loopStart > loopEnd) then
			error('loop cannot end.')
		end
		loopRange = loopRange * (opt.loopWeight or 1)
		if opt.validateCondition then
			validateCondition(loopStart, loopEnd, loopRange)
		end
		if yesno(args.delnowiki) then
			loopContent = mw.text.unstripNoWiki(loopContent)
		end
		if yesno(args.delmsgnw) then
			loopContent = mw.text.decode(loopContent)
		end
		if yesno(args.usingConditionalExpressions) then
			if not mTemplateParameters then
				mTemplateParameters = require('Module:TemplateParameters')
			end
			loopContent = mTemplateParameters._get_escape(loopContent)
		end
		local i = loopStart
		local check_stop = opt.stopCondition(loopStart, loopEnd, loopRange)
		local numbers = {}
		while true do
			numbers[#numbers + 1] = i
			i = i + loopRange
			if check_stop(i) then
				break
			end
		end
		local output = ''
		for index, number in ipairs(numbers) do
			output = output .. loopContent
				:gsub('{{{1}}}', tostring(number))
				:gsub('{{{last}}}', index > 1 and tostring(numbers[index - 1]) or '')
				:gsub('{{{current}}}', tostring(number))
				:gsub('{{{next}}}', index < #numbers and tostring(numbers[index + 1]) or '')
		end
		return mw.getCurrentFrame():preprocess(output)
	end
end

p._increment = p._loop({
	loopWeight = 1,
	stopCondition = function (loopStart, loopEnd, loopRange)
		return function (i)
			return i > loopEnd
		end
	end
})

function p.increment(frame)
	return p._increment(frame)
end

p._decrement = p._loop({
	loopWeight = -1,
	stopCondition = function (loopStart, loopEnd, loopRange)
		return function (i)
			return i < loopEnd
		end
	end
})

function p.decrement(frame)
	return p._decrement(frame)
end

return p