모듈:Pipeline: 두 판 사이의 차이

리버티게임, 모두가 만들어가는 자유로운 게임
편집 요약 없음
편집 요약 없음
132번째 줄: 132번째 줄:
end
end
for key, value in pairs(passed) do
if passed then
if iferror(value) then
for key, value in pairs(passed) do
table.insert(err, value)
if iferror(value) then
table.insert(err, value)
end
end
end
end
end

2024년 12월 21일 (토) 19:39 판


모듈 설명문서[보기] [편집] [역사] [새로 고침]

이전 값에 종속되는 여러 틀을 연속적으로 실행합니다. 이를 통해 복잡한 로직을 함수형으로 구현하거나 중첩된 틀을 가독성 좋게 바꿀 수 있습니다.

사용법

code_blocks 코드
{{#invoke:Pipeline|pipe |{{#invoke:pipeline|pass|9|a=10}}11 |<nowiki>{{#expr:{{{1}}}+{{{a}}}+{{RETURNED}}}}</nowiki> }}
code
낙서장에서 확인
description 결과
30

이전에 실행된 함수의 값을 RETURNED 상수를 통해 통째로 다음 함수에 넘겨줍니다. pass 함수를 활용하여 여러 값을 넘겨줄 수 있습니다.


local p = {}
local tf = require('모듈:TemplateFunction')
local random = require('모듈:Random')

local passRandStr = random.id(6, os.time())
local passTag = 'pipe-passed-data--' .. passRandStr
local passTagPattern = 'pipe%-passed%-data%-%-' .. passRandStr
local passPattern = '<' .. passTagPattern .. '>(.-)</' .. passTagPattern.. '>'

function iferror(wt)
	local frame = mw.getCurrentFrame()
	local result = frame:callParserFunction('#iferror', wt, 1, 0)
	
	if result == '1' then
		return true
	elseif result == '0' then
		return false
	else
		error('Cannot detect error')
	end
end

function p.pipe(frame)
	local returned = ''
	local passed = nil
	
	-- 한 단계씩 파싱
	for _, source in ipairs(frame.args) do
		local title = mw.title.new(source, 'Template')
		
		-- RETURNED 파싱
		source = mw.text.unstripNoWiki(mw.text.decode(source)):gsub('{{RETURNED}}', function(default)
			return returned or ''
		end)
		
		if title and title.exists then
			-- 틀/문서 제목과 일치할 경우 틀로 처리
			returned = tf.load(source):parse(passed)
		elseif not pcall(function()
			-- 파서 함수 이름과 일치할 경우 파서 함수로 처리
			returned = frame:callParserFunction(source, passed)
		end) then
			-- 아니면 인라인 위키텍스트로 처리
			
			returned = tf.create(source):parse(passed) -- 이전 반환값 위키텍스트 파싱
			passed = returned:match(passPattern) -- pass 인자로 넘겨줄 부분: #pass 부분만 추출
			passed = passed and mw.text.jsonDecode(passed) -- pass 부분 테이블로 파싱
			returned = returned:gsub(passPattern, '') -- RETURNED로 넘겨줄 부분: #pass 부분 제외
		end
	end
	
	return returned
end

function p.from(args)
	return '<' .. passTag .. '>'
		.. mw.text.jsonEncode(args)
		.. '</' .. passTag .. '>'
end

function p.pass(frame)
	return p.from(frame.args)
end

function p.debug(frame)
	local tableView = require('모듈:TableView')
	local returned = ''
	local passed = nil
	local err = {}
	local printed = 'passTag = ' .. passTag .. '<br />'
	
	-- 한 단계씩 파싱
	for i, source in ipairs(frame.args) do
		err = {}
		local title = mw.title.new(source, 'Template')
		
		printed = printed .. '[#' .. i .. ']<br />source = ' .. frame:extensionTag('pre', source)
		
		if passed then
			printed = printed .. '#passed = ' .. tostring(tableView.kv(passed, {
				header = true,
				attr = {
					class = 'wikitable'
				},
				transformer = function(key, value)
					return key, mw.text.nowiki(value)
				end
			}))
		end
		-- RETURNED 파싱
		source = mw.text.unstripNoWiki(mw.text.decode(source)):gsub('{{RETURNED}}', function(default)
			return returned or ''
		end)
		
		if title and title.exists then
			-- 틀/문서 제목과 일치할 경우 틀로 처리
			printed = printed .. 'template = ' .. source .. '<br />'
			returned = tf.load(source):parse(passed)
			printed = printed .. 'RETURNED raw = ' .. frame:extensionTag('pre', returned) .. '<br />RETURNED parsed = ' .. returned
		elseif not pcall(function()
			-- 파서 함수 이름과 일치할 경우 파서 함수로 처리
			returned = frame:callParserFunction(source, passed)
			printed = printed .. 'parserFunction = ' .. source .. '<br />'
			printed = printed .. 'RETURNED raw = ' .. frame:extensionTag('pre', returned) .. '<br />RETURNED parsed = ' .. returned
		end) then
			-- 아니면 인라인 위키텍스트로 처리
			printed = printed .. '<br />wikitext = ' .. frame:extensionTag('pre', source) .. '<br />'
			
			returned = tf.create(source):parse(passed) -- 이전 반환값 위키텍스트 파싱
			passed = returned:match(passPattern) -- pass 인자로 넘겨줄 부분: #pass 부분만 추출
			passed = passed and mw.text.jsonDecode(passed) -- pass 부분 테이블로 파싱
			returned = returned:gsub(passPattern, '') -- RETURNED로 넘겨줄 부분: #pass 부분
			printed = printed .. 'RETURNED raw = ' .. frame:extensionTag('pre', returned) .. '<br />RETURNED parsed = ' .. returned
			
			printed = printed .. '<br />matched #pass = ' .. mw.text.jsonEncode(passed)
			
			if passed then
				printed = printed .. '<br />#passed = ' .. tostring(tableView.kv(passed, {
					header = true,
					attr = {
						class = 'wikitable'
					},
					transformer = function(key, value)
						return key, mw.text.nowiki(value)
					end
				}))
			end
		end
		
		if iferror(returned) then
			table.insert(err, returned)
		end
		
		if passed then
			for key, value in pairs(passed) do
				if iferror(value) then
					table.insert(err, value)
				end
			end
		end
		
		printed = printed .. '<br />errors = ' .. table.concat(err, ',')
	end
	
	printed = printed .. '<br />\n----'
	
	return printed
end


return p