모듈:Category

최근 편집: 2017년 8월 4일 (금) 05:02
낙엽1124 (토론 | 기여)님의 2017년 8월 4일 (금) 05:02 판 (분류가 넘겨주기되면 넘겨주기 된 이름이 표시되도록 합니다.)

알려진 문제

순환 참조가 발생했을 시 ?action=edit으로 내용을 변경하기 전까지 문서 로딩이 되지 않습니다.


local p = {}

--문서 하단에서 볼 수 있는 분류들을 볼 수 있는 문단 만들기
local function catlinksDiv(categoryBundles, frame)
	local listItems = ''
	for i, v in ipairs(categoryBundles) do
		listItems = listItems .. frame:callParserFunction( '#tag:li', '[[:분류:'..v[1]..'/'..v[2]..'|'..v[1]..'/'..v[2]..']]' )
	end

	return frame:callParserFunction{
		name = '#tag:div', 
		args = {
			id = 'fw-catlinks', 
			class = 'fw-catlinks catlinks', 
			['data-mw'] = 'interface', 
			frame:callParserFunction{
				name = '#tag:div', args = {
					class = 'mw-normal-catlinks',
					'[[특수:다면분류|분류]]:'
					.. frame:callParserFunction('#tag:ul', listItems)
				}
			}
		}
	}
end

--문서를 분류할 때 사용하는 함수
local function _categorize(catlinks, categoryBundles, frame)
	if categoryBundles == nil then return '' end

	local returnText, ttl = '', ''

	for i, v in ipairs(categoryBundles) do
		if v[1] == nil or v[2] == nil then
			error("사용하신 분류 문법이 잘못되었습니다. [[도움말:문서 분류하기]]를 참고해 주세요.",0)
			return ''
		end

		ttl = mw.title.new('분류:' .. v[1]  .. '/' .. v[2])
		if ttl.exists and ttl.isRedirect then
			ttl =  mw.title.new(string.match(ttl:getContent(),"%[%[([^%[%]|]-)%]%]")) or ttl
			v[1] = p.facet(ttl.text)
			v[2] = p.member(ttl.text)
		end

		returnText = returnText .. '[[분류:' .. v[1]  .. '/' .. v[2] .. ']]'

		if ttl.exists then
			if frame:expandTemplate{ title = ttl.fullText, args = {'supercategory'} } == 'yes' then
				returnText = returnText .. frame:expandTemplate{ title = '분류:' .. v[1]  .. "/" .. v[2] }
			end
		end
	end

	if catlinks then
		returnText = returnText .. catlinksDiv(categoryBundles, frame)
	end

	return returnText
end

--분류를 분류할 때 사용하는 함수
local function _categorizeCategory(categoryBundles) 
	if categoryBundles == nil then return '' end

	local returnText = '<onlyinclude>{{#ifeq:{{{1|}}}|supercategory|yes|{{#invoke:category|categorize'

	for k, v in pairs(categoryBundles) do
		if v[1] == nil or v[2] == nil then
			error("사용하신 분류 문법이 잘못되었습니다. [[도움말:문서 분류하기]]를 참고해 주세요.",0)
			return ''
		end

		if k == 1 then returnText = returnText .. '|' 
		else returnText = returnText .. ', ' 
		end

		returnText = returnText .. v[1] .. '/' .. v[2]
	end

	returnText = returnText .. '<noinclude>|catlinks=yes</noinclude>}}}}</onlyinclude>'

	return returnText
end

--틀에서 호출되거나 바로 모듈이 호출되거나 상관없이 매개변수에 접근할 수 있도록 합니다.
local function safeArgs(frame)
	if frame.args[1] ~= nil then --frame은 metatable이라 next(frame.args)가 안 된다고 하여 이리 되었습니다.
		return frame.args
	else
		return frame:getParent().args
	end
end

--패싯과 패싯 멤버를 묶습니다.
local function bundle(args)
	--{{분류|성격/단체, 성향/페미니즘}} 식으로 호출되었으면 매개변수들을 적당히 분리합니다.
	local temp = {}
	if string.match(args[1],',') ~= nil then
		for word in string.gmatch(args[1],'%s*([^,]+)%s*') do
			temp[#temp+1] = word
		end
		args = temp
	elseif #args==1 and string.match(args[1],'/') == nil then 
		error('사용하신 구문은 다면분류가 아닙니다. [[도움말:문서 분류하기]]를 참고해 주세요.',0)
		return nil
	end

	--매개변수들이 '성격/단체', '성향/페미니즘'식으로 왔다면 분리합니다.
	if string.find(args[1],'/') ~= nil then
		temp = {}
		for i, v in ipairs(args) do
			temp[#temp + 1] = string.match(v,"([^/]+)/")
			temp[#temp + 1] = string.match(v, "/(.+)")
		end
		args = temp
	end

	--공백을 제거하고 번들로 만듭니다.
	local bundles = {}
	for i, v in ipairs(args) do
		if i % 2 ~= 0 then
			bundles[#bundles+1] = {string.match(v,"^%s*(.-)%s*$")}
		else
			bundles[#bundles][2] = string.match(v,"^%s*(.-)%s*$")
		end
	end

	return bundles
end

--만약 "{{#invoke:Category|main|성격/단체, 성향/페미니즘}}""
--과 같이 호출되었다면 다음 작업을 수행합니다.
--  우선 문서에 "[[분류:성격/단체]]"를 추가합니다.
--  "분류:성격/단체"라는 문서가 있는지, 있다면 상위분류가 있는지를 확인합니다.
--	  둘다 맞다면 문서에 "분류:성격/단체"를 전개하여 추가합니다.(해당 틀은 이 함수를 재귀호출합니다.)
--  성향/페미니즘에 대해서도 같은 작업을 수행합니다.
function p.categorize(frame)
	origArgs = safeArgs(frame)

	local onlyCategoryArgs = {} --예를 들어 {'성격', '단체', '성향', '페미니즘'} 혹은 {'성격/단체', '성향/페미니즘'}
	for k, v in pairs( origArgs ) do
		--k가 자연수라면
		if type( k ) == 'number' and k >= 1 and math.floor( k ) == k then
			table.insert( onlyCategoryArgs, k )
		end
	end
	table.sort( onlyCategoryArgs )
	for i,v in ipairs( onlyCategoryArgs ) do
		onlyCategoryArgs[i] = origArgs[v]
	end

	return _categorize(frame.args['catlinks']~=nil and true or false, bundle(onlyCategoryArgs), frame)
end

--분류를 분류할 때 사용하는 함수
function p.categorizeCategory(frame) 
	return _categorizeCategory(bundle(safeArgs(frame)))
end

--"A/B"를 인자로 받으면 패싯인 A를 반환하는 함수
function p.facet(frame)
	if type(frame) ~= 'string' then local text = frame.args[1]
	else text = frame end
	local slash = string.find(text,'/')
	if slash == nil then return text end 
	return string.sub(text,1,slash-1)
end

--"A/B"를 인자로 받으면 멤버인 B를 반환하는 함수
function p.member(frame)
	if type(frame) ~= 'string' then local text = frame.args[1]
	else text = frame end
	local slash = string.find(text,'/')
	if slash == nil then return text end
	return string.sub(text,slash+1,#text)
end

return p