<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ko">
	<id>https://akadia.kr/wiki/index.php?action=history&amp;feed=atom&amp;title=%EB%AA%A8%EB%93%88%3A%EA%B8%B0%EA%B4%80%EC%A0%95%EB%B3%B4</id>
	<title>모듈:기관정보 - 편집 역사</title>
	<link rel="self" type="application/atom+xml" href="https://akadia.kr/wiki/index.php?action=history&amp;feed=atom&amp;title=%EB%AA%A8%EB%93%88%3A%EA%B8%B0%EA%B4%80%EC%A0%95%EB%B3%B4"/>
	<link rel="alternate" type="text/html" href="https://akadia.kr/wiki/index.php?title=%EB%AA%A8%EB%93%88:%EA%B8%B0%EA%B4%80%EC%A0%95%EB%B3%B4&amp;action=history"/>
	<updated>2026-05-31T15:02:44Z</updated>
	<subtitle>이 문서의 편집 역사</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://akadia.kr/wiki/index.php?title=%EB%AA%A8%EB%93%88:%EA%B8%B0%EA%B4%80%EC%A0%95%EB%B3%B4&amp;diff=332&amp;oldid=prev</id>
		<title>Admin: 기관 인포박스 파라미터 추출 Lua 모듈 생성</title>
		<link rel="alternate" type="text/html" href="https://akadia.kr/wiki/index.php?title=%EB%AA%A8%EB%93%88:%EA%B8%B0%EA%B4%80%EC%A0%95%EB%B3%B4&amp;diff=332&amp;oldid=prev"/>
		<updated>2026-05-08T16:47:21Z</updated>

		<summary type="html">&lt;p&gt;기관 인포박스 파라미터 추출 Lua 모듈 생성&lt;/p&gt;
&lt;p&gt;&lt;b&gt;새 문서&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Module:기관정보&lt;br /&gt;
-- 위키 페이지의 {{Infobox ...}} 인포박스에서 특정 파라미터 값을 추출한다.&lt;br /&gt;
-- 「한국의 아카이브」 디렉토리가 각 기관 페이지의 인포박스를 단일 데이터 소스로 사용할 수 있게 해준다.&lt;br /&gt;
--&lt;br /&gt;
-- 사용법:&lt;br /&gt;
--   {{#invoke:기관정보|field|페이지이름|필드명}}&lt;br /&gt;
-- 예시:&lt;br /&gt;
--   {{#invoke:기관정보|field|국가기록원|소재지}}&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Lua 패턴 메타문자 이스케이프&lt;br /&gt;
local function escapePattern(s)&lt;br /&gt;
	return (s:gsub(&amp;#039;([%(%)%.%%%+%-%*%?%[%]%^%$])&amp;#039;, &amp;#039;%%%1&amp;#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 위키텍스트에서 첫 번째 {{Infobox ...}} 블록의 위치(시작·끝)를 반환&lt;br /&gt;
local function findInfobox(content)&lt;br /&gt;
	if not content then return nil, nil end&lt;br /&gt;
&lt;br /&gt;
	local startIdx = content:find(&amp;#039;{{Infobox&amp;#039;, 1, true)&lt;br /&gt;
	if not startIdx then return nil, nil end&lt;br /&gt;
&lt;br /&gt;
	local depth = 1&lt;br /&gt;
	local i = startIdx + 9&lt;br /&gt;
	while i &amp;lt;= #content do&lt;br /&gt;
		local two = content:sub(i, i + 1)&lt;br /&gt;
		if two == &amp;#039;{{&amp;#039; then&lt;br /&gt;
			depth = depth + 1&lt;br /&gt;
			i = i + 2&lt;br /&gt;
		elseif two == &amp;#039;}}&amp;#039; then&lt;br /&gt;
			depth = depth - 1&lt;br /&gt;
			if depth == 0 then&lt;br /&gt;
				return startIdx, i + 1&lt;br /&gt;
			end&lt;br /&gt;
			i = i + 2&lt;br /&gt;
		else&lt;br /&gt;
			i = i + 1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return nil, nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 인포박스에서 특정 파라미터 값을 추출&lt;br /&gt;
local function getInfoboxParam(content, paramName)&lt;br /&gt;
	local startIdx, endIdx = findInfobox(content)&lt;br /&gt;
	if not startIdx then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
	local infoboxText = content:sub(startIdx, endIdx)&lt;br /&gt;
&lt;br /&gt;
	local pattern = &amp;#039;|%s*&amp;#039; .. escapePattern(paramName) .. &amp;#039;%s*=&amp;#039;&lt;br /&gt;
	local s, e = infoboxText:find(pattern)&lt;br /&gt;
	if not s then return &amp;#039;&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
	local valueStart = e + 1&lt;br /&gt;
	while valueStart &amp;lt;= #infoboxText and infoboxText:sub(valueStart, valueStart):match(&amp;#039;%s&amp;#039;) do&lt;br /&gt;
		valueStart = valueStart + 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- 값의 끝을 찾는다: 균형 맞춰 중첩 처리, 최상위 레벨의 | 또는 최종 }} 직전까지&lt;br /&gt;
	local depth = 0&lt;br /&gt;
	local i = valueStart&lt;br /&gt;
	while i &amp;lt;= #infoboxText do&lt;br /&gt;
		local two = infoboxText:sub(i, i + 1)&lt;br /&gt;
		local one = infoboxText:sub(i, i)&lt;br /&gt;
&lt;br /&gt;
		if two == &amp;#039;{{&amp;#039; or two == &amp;#039;[[&amp;#039; then&lt;br /&gt;
			depth = depth + 1&lt;br /&gt;
			i = i + 2&lt;br /&gt;
		elseif two == &amp;#039;}}&amp;#039; or two == &amp;#039;]]&amp;#039; then&lt;br /&gt;
			if depth &amp;gt; 0 then&lt;br /&gt;
				depth = depth - 1&lt;br /&gt;
				i = i + 2&lt;br /&gt;
			else&lt;br /&gt;
				return mw.text.trim(infoboxText:sub(valueStart, i - 1))&lt;br /&gt;
			end&lt;br /&gt;
		elseif depth == 0 and one == &amp;#039;|&amp;#039; then&lt;br /&gt;
			return mw.text.trim(infoboxText:sub(valueStart, i - 1))&lt;br /&gt;
		else&lt;br /&gt;
			i = i + 1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return &amp;#039;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 공개 함수: 페이지 인포박스에서 필드 값을 가져옴&lt;br /&gt;
function p.field(frame)&lt;br /&gt;
	local pageName = frame.args[1]&lt;br /&gt;
	local fieldName = frame.args[2]&lt;br /&gt;
&lt;br /&gt;
	if not pageName or pageName == &amp;#039;&amp;#039; or not fieldName or fieldName == &amp;#039;&amp;#039; then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local title = mw.title.new(pageName)&lt;br /&gt;
	if not title or not title.exists then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local content = title:getContent()&lt;br /&gt;
	if not content then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return getInfoboxParam(content, fieldName)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>