이 모듈에 대한 설명문서는 모듈:기관정보/설명문서에서 만들 수 있습니다

-- Module:기관정보
-- 위키 페이지의 {{Infobox ...}} 인포박스에서 특정 파라미터 값을 추출한다.
-- 「한국의 아카이브」 디렉토리가 각 기관 페이지의 인포박스를 단일 데이터 소스로 사용할 수 있게 해준다.
--
-- 사용법:
--   {{#invoke:기관정보|field|페이지이름|필드명}}
-- 예시:
--   {{#invoke:기관정보|field|국가기록원|소재지}}

local p = {}

-- Lua 패턴 메타문자 이스케이프
local function escapePattern(s)
	return (s:gsub('([%(%)%.%%%+%-%*%?%[%]%^%$])', '%%%1'))
end

-- 위키텍스트에서 첫 번째 {{Infobox ...}} 블록의 위치(시작·끝)를 반환
local function findInfobox(content)
	if not content then return nil, nil end

	local startIdx = content:find('{{Infobox', 1, true)
	if not startIdx then return nil, nil end

	local depth = 1
	local i = startIdx + 9
	while i <= #content do
		local two = content:sub(i, i + 1)
		if two == '{{' then
			depth = depth + 1
			i = i + 2
		elseif two == '}}' then
			depth = depth - 1
			if depth == 0 then
				return startIdx, i + 1
			end
			i = i + 2
		else
			i = i + 1
		end
	end

	return nil, nil
end

-- 인포박스에서 특정 파라미터 값을 추출
local function getInfoboxParam(content, paramName)
	local startIdx, endIdx = findInfobox(content)
	if not startIdx then return '' end

	local infoboxText = content:sub(startIdx, endIdx)

	local pattern = '|%s*' .. escapePattern(paramName) .. '%s*='
	local s, e = infoboxText:find(pattern)
	if not s then return '' end

	local valueStart = e + 1
	while valueStart <= #infoboxText and infoboxText:sub(valueStart, valueStart):match('%s') do
		valueStart = valueStart + 1
	end

	-- 값의 끝을 찾는다: 균형 맞춰 중첩 처리, 최상위 레벨의 | 또는 최종 }} 직전까지
	local depth = 0
	local i = valueStart
	while i <= #infoboxText do
		local two = infoboxText:sub(i, i + 1)
		local one = infoboxText:sub(i, i)

		if two == '{{' or two == '[[' then
			depth = depth + 1
			i = i + 2
		elseif two == '}}' or two == ']]' then
			if depth > 0 then
				depth = depth - 1
				i = i + 2
			else
				return mw.text.trim(infoboxText:sub(valueStart, i - 1))
			end
		elseif depth == 0 and one == '|' then
			return mw.text.trim(infoboxText:sub(valueStart, i - 1))
		else
			i = i + 1
		end
	end

	return ''
end

-- 공개 함수: 페이지 인포박스에서 필드 값을 가져옴
function p.field(frame)
	local pageName = frame.args[1]
	local fieldName = frame.args[2]

	if not pageName or pageName == '' or not fieldName or fieldName == '' then
		return ''
	end

	local title = mw.title.new(pageName)
	if not title or not title.exists then
		return ''
	end

	local content = title:getContent()
	if not content then
		return ''
	end

	return getInfoboxParam(content, fieldName)
end

return p