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

리버티게임(개발), 모두가 만들어가는 자유로운 게임
둘러보기로 이동 검색으로 이동
>Hsl0
편집 요약 없음
>Hsl0
편집 요약 없음
 
(같은 사용자의 중간 판 8개는 보이지 않습니다)
2번째 줄: 2번째 줄:
local frame = mw.getCurrentFrame()
local frame = mw.getCurrentFrame()
local Template = {}
local Template = {}
local ParserFunction = {}
function concat(a, b)
return tostring(a) .. tostring(b)
end
function contains(tbl, item)
for value in ipairs(tbl) do
if value == item then
return true
end
end
return false
end


function Template:parse(args)
function Template:parse(args)
return frame:preprocess(mw.text.decode(mw.text.unstripNoWiki(self.source)):gsub("{{{%f[^{](.-)}}}", function(exp)
return frame:preprocess(mw.text.decode(mw.text.unstripNoWiki(self.source)):gsub("{{{%f[^{](.-)}}}", function(exp)
local group = mw.text.split(exp, "|")
local group = mw.text.split(exp, "|")
return args and args[tonumber(group[1]) or group[1]] or group[2]
local key = table.remove(group, 1)
return args and args[tonumber(key) or key] or table.concat(group, '|')
end))
end))
end
end


function Template:curry(args)
function Template:curry(args)
local length = 0
local length = #args
for key in ipairs(args) do
return p.create(mw.text.decode(mw.text.unstripNoWiki(self.source)):gsub("{{{%f[^{](.-)}}}", function(exp)
length = key
end
return p.new(mw.text.decode(mw.text.unstripNoWiki(self.source)):gsub("{{{%f[^{](.-)}}}", function(exp)
local group = mw.text.split(exp, "|")
local group = mw.text.split(exp, "|")
local key = tonumber(group[1]) or group[1]
local key = tonumber(group[1]) or group[1]
local result = args and args[key]
local result = args and args[key]
table.remove(group, 1)
if result then
if result then
27번째 줄: 40번째 줄:
key = key - length
key = key - length
return group[2]
return group[2]
and '{{{' .. key .. '|' .. group[2] .. '}}}'
and '{{{' .. key .. '|' .. table.concat(group, '|') .. '}}}'
or '{{{' .. key .. '}}}'
or '{{{' .. key .. '}}}'
end
end
33번째 줄: 46번째 줄:
end
end


function p.new(source)
function Template:forward(mappings)
return p.create(mw.text.decode(mw.text.unstripNoWiki(self.source)):gsub("{{{%f[^{](.-)}}}", function(exp)
local group = mw.text.split(exp, "|")
local key = table.remove(group, 1)
key = mappings and mappings[key] or tonumber(key) and mappings[tonumber(key)] or key
 
return #group >= 1
and '{{{' .. key .. '|' .. table.concat(group, '|') .. '}}}'
or '{{{' .. key .. '}}}'
end))
end
 
function Template:finalize(keys)
local cache = {}
if not keys then
return p.create(self:parse())
end
return p.create(mw.text.decode(mw.text.unstripNoWiki(self.source)):gsub("{{{%f[^{](.-)}}}", function(exp)
local group = mw.text.split(exp, "|")
local key = table.remove(group, 1)
if cache[key] == nil then
cache[key] = contains(keys, key)
end
if cache[key] and #group >= 1 then
return table.concat(group, '|')
end
end))
end
 
function ParserFunction:curry(args)
local newargs = {}
local length = #self.args
for key, value in pairs(self.args) do
newargs[key] = value
end
for key, value in pairs(args) do
key = tonumber(key) or key
if type(key) == 'number' and key <= #args then
key = key + length
end
newargs[key] = value
end
return p.import(self.name, newargs)
end
 
function ParserFunction:parse(args)
if args then
return self:curry(args):parse()
end
return frame:callParserFunction(self.name, self.args)
end
 
function p.create(source)
return setmetatable({
return setmetatable({
source = source
source = source
39번째 줄: 112번째 줄:
__index = Template,
__index = Template,
__call = Template.curry,
__call = Template.curry,
__tostring = Template.parse
__tostring = Template.parse,
__concat = concat
})
})
end
function p.load(pagename)
local title = mw.title.new(pagename, 'Template')
local matches = ''
while title.isRedirect do
title = title.redirectTarget
end
for match in title:getContent():gmatch('<onlyinclude>(.-)</onlyinclude>') do
matches = matches .. match
end
return p.create(matches:gsub('</?includeonly>', ''))
end
function p.import(name, _args)
return setmetatable({
name = name,
args = _args or {}
}, {
__index = ParserFunction,
__call = ParserFunction.curry,
__tostring = ParserFunction.parse,
__concat = concat
})
end
function p.importTag(name)
return p.import('#tag'):curry{name}
end
end


return p
return p

2024년 2월 12일 (월) 12:31 기준 최신판


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

내보낸 값

create

local tf = require('모듈:TemplateFunction')
local hello = tf.create('Hello, {{{1}}}!')
print(hello{'world'}) -- Hello, World!

루아 모듈 내에서 간단한 위키텍스트 틀을 만들어 실행시킬 수 있는 틀 객체를 만드는 함수입니다. 인자에 위키텍스트 소스 코드를 입력해 주세요.

load

local tf = require('모듈:TemplateFunction')
local user = tf.load('USERNAME')

기존의 문서나 틀을 실행 가능한 틀 객체로 만드는 함수입니다. 인자에 이름공간을 생략한 틀 이름이나 이름공간을 포함한 문서 제목을 입력해 주세요. 기본 이름공간은 :(콜론)으로 시작해야 합니다.

import

local tf = require('모듈:TemplateFunction')
local urlget = tf.import('urlget')
print(urlget{'undefined'})

기존의 파서 함수나 상수를 실행가능한 틀 객체로 만드는 함수입니다. 인자에 파서 함수 이름을 입력해주세요. #으로 시작하는 파서 함수는 #도 포함해야 합니다.

importTag

local tf = require('모듈:TemplateFunction')
local nowiki = tf.importTag('nowiki')
print(nowiki{"[[리버티게임:대문]]"})

기존의 파서 태그를 실행가능한 틀 객체로 만드는 함수입니다. 인자에 태그 이름을 입력하세요. 이 함수는 #tag 파서 함수의 Syntactic sugar입니다.

틀 객체

local tf = require('모듈:TemplateFunction')
local hello = tf.create('{{{1}}}, {{{2|World}}}!')

local hi = hello:curry{'Hi'}
print(hi.source) -- Hi, {{{1|World}}}!

print(hi:parse()) -- Hi, World!
print(tostring(hi)) -- Hi, World!
print(hi) -- Hi, World!
print(hi:parse{'Libertygame'}) -- Hi, Libertygame!


local liberty = hi{'Libertygame'}
print(liberty) -- Hi, Libertygame!
print(liberty.source) -- Hi, Libertygame!

틀 객체는 이 모듈에 포함된 각종 함수를 통해 생성합니다. 틀 객체는 함수처럼 호출할 수 있으며, 이 경우 curry 메소드 처럼 동작합니다. 이 객체를 문자열로 변환하면 parse 메소드가 내부적으로 실행됩니다.

source

틀 객체의 위키텍스트 원본 소스 코드를 저장합니다. create나 load로 생성한 객체에만 존재합니다.

name

틀 객체가 연결된 파서 함수의 이름을 저장합니다. import나 importTag로 생성한 객체에만 존재합니다.

args

기존에 바인딩된 변수를 저장합니다. import나 importTag로 생성한 객체에만 존재합니다.

curry

기존 틀에서 변수를 부분적으로 적용시킨 새로운 틀 객체를 반환합니다. 값이 확정되지 않은 숫자 변수는 다음 커링 호출 때 이어서 받아들일 수 있도록 변수명을 앞당깁니다. 다음에 숫자 변수로 할당되는 익명 인자는 값이 확정된 마지막 숫자 키의 다음 숫자 키부터 할당됩니다. 이 메소드는 위키텍스트의 커링을 구현합니다.

parse

기존 틀에서 변수를 적용시켜서 완전히 처리된 문자열로 만듭니다. 변수가 확정되지 않으면 기본값으로 대치됩니다. 틀 객체를 문자열로 변환할 경우에도 인자가 주어지지 않은 parse 메소드처럼 작동합니다.

forward

기존 틀에서 받아들이는 변수의 키를 바꿉니다. 이 메소드에 주어지는 테이블의 키는 기존 변수고, 값은 새로운 변수입니다.

finalize

특정 키에 대해 더 이상 값을 받지 않고, 확정되지 않은 키는 기본값으로 고정합니다.


local p = {}
local frame = mw.getCurrentFrame()
local Template = {}
local ParserFunction = {}

function concat(a, b)
	return tostring(a) .. tostring(b)
end

function contains(tbl, item)
	for value in ipairs(tbl) do
		if value == item then
			return true
		end
	end
	return false
end

function Template:parse(args)
	return frame:preprocess(mw.text.decode(mw.text.unstripNoWiki(self.source)):gsub("{{{%f[^{](.-)}}}", function(exp)
		local group = mw.text.split(exp, "|")
		local key = table.remove(group, 1)
		return args and args[tonumber(key) or key] or table.concat(group, '|')
	end))
end

function Template:curry(args)
	local length = #args
	
	return p.create(mw.text.decode(mw.text.unstripNoWiki(self.source)):gsub("{{{%f[^{](.-)}}}", function(exp)
		local group = mw.text.split(exp, "|")
		local key = tonumber(group[1]) or group[1]
		local result = args and args[key]
		
		table.remove(group, 1)
		
		if result then
			return result
		elseif type(key) == 'number' and key > length then
			key = key - length
			return group[2]
				and '{{{' .. key .. '|' .. table.concat(group, '|') .. '}}}'
				or '{{{' .. key .. '}}}'
		end
	end))
end

function Template:forward(mappings)
	return p.create(mw.text.decode(mw.text.unstripNoWiki(self.source)):gsub("{{{%f[^{](.-)}}}", function(exp)
		local group = mw.text.split(exp, "|")
		local key = table.remove(group, 1)
		key = mappings and mappings[key] or tonumber(key) and mappings[tonumber(key)] or key

		return #group >= 1
			and '{{{' .. key .. '|' .. table.concat(group, '|') .. '}}}'
			or '{{{' .. key .. '}}}'
	end))
end

function Template:finalize(keys)
	local cache = {}
	
	if not keys then
		return p.create(self:parse())
	end
	
	return p.create(mw.text.decode(mw.text.unstripNoWiki(self.source)):gsub("{{{%f[^{](.-)}}}", function(exp)
		local group = mw.text.split(exp, "|")
		local key = table.remove(group, 1)
		
		if cache[key] == nil then
			cache[key] = contains(keys, key)
		end
		
		if cache[key] and #group >= 1 then
			return table.concat(group, '|')
		end
	end))
end

function ParserFunction:curry(args)
	local newargs = {}
	local length = #self.args
	
	for key, value in pairs(self.args) do
		newargs[key] = value
	end
	
	for key, value in pairs(args) do
		key = tonumber(key) or key
		if type(key) == 'number' and key <= #args then
			key = key + length
		end
		newargs[key] = value
	end
	
	return p.import(self.name, newargs)
end

function ParserFunction:parse(args)
	if args then
		return self:curry(args):parse()
	end
	
	return frame:callParserFunction(self.name, self.args)
end

function p.create(source)
	return setmetatable({
		source = source
	}, {
		__index = Template,
		__call = Template.curry,
		__tostring = Template.parse,
		__concat = concat
	})
end

function p.load(pagename)
	local title = mw.title.new(pagename, 'Template')
	local matches = ''
	
	while title.isRedirect do
		title = title.redirectTarget
	end
	
	for match in title:getContent():gmatch('<onlyinclude>(.-)</onlyinclude>') do
		matches = matches .. match
	end
	
	return p.create(matches:gsub('</?includeonly>', ''))
end

function p.import(name, _args)
	return setmetatable({
		name = name,
		args = _args or {}
	}, {
		__index = ParserFunction,
		__call = ParserFunction.curry,
		__tostring = ParserFunction.parse,
		__concat = concat
	})
end

function p.importTag(name)
	return p.import('#tag'):curry{name}
end

return p