모듈:module documentation

이 모듈은 다른 모듈을 위한 설명문서를 자동으로 생성합니다. Lua 코드 내의 인라인 주석을 가져와 {{모듈 설명문서}} 을 통해 설명문서 페이지에 사용할 수 있는 형식으로 변환합니다. 이 모듈의 설명문서는 이 모듈이 작동하는 예시입니다.

설명문서는 모듈 페이지의 맨 위(일반적인 위키텍스트 형태)와 함수 자체 상단(Lua 주석 형태)에 표시되어 있어 이 방식으로 설명문서를 작성하는 데 용이합니다. 각각이 다른 편집 스타일에 적합하며, 이러한 방식으로 두 형태의 코드를 동기화할 수 있습니다.

설명문서 부분은 Lua의 다중 주석 구문(--[==[ ... ]==])에 의해 구성됩니다. 일반적으로 {{모듈 설명문서}}에 설명 문서를 올바르게 표시하려면 등호가 두 개 필요합니다. 설명문서 내에서는 다음과 같은 규칙을 이용할 수 있습니다.

  1. 긴 줄(일반 문단 및 목록 항목)은 선택적으로 스페이스나 탭 뒤에 따라오는 새 줄에 의해 개행될 수 있습니다. 이는 목록에서 raw 주석의 가독성을 높이기 위해 유용한 방법입니다. 이 경우, 새 줄은 공백으로 변환됩니다. 두 개의 연속된 새 줄을 이용하여 단락을 나눌 수 있습니다. raw 주석을 읽기 쉽게 하기 위한 줄 바꿈은 일반적으로 최대 120자 이내에서 이루어지는 것이 권장됩니다.
  2. 이중 중괄호를 이용한 템플릿 호출은 그대로 삽입되며 확장됩니다.
  3. 단일 중괄호는 글자 그대로의 텍스트를 둘러싸고, Lua 코드로 구문을 강조 처리하는 데 쓰입니다. 이 문자열 내의 중첩된 중괄호는 짝이 맞게 배치되어 있다면 올바르게 처리됩니다. 텍스트 첫 글자가 중괄호인 경우, 앞에 공백을 두면 이를 Lua 구문으로 읽어들이지 않습니다. 끝에는 공백을 넣으면 안 됩니다.
  4. 백쿼트(`)는 매개변수명을 감싸는 데 사용되며, <code class="n">...</code>를 사용하여 표시됩니다. 백쿼트 내의 내용은 문자, 숫자, 밑줄, 붙임표(하이픈), 점만 포함되어야 합니다.
  5. 이중 백쿼트(``)는 대체변수명을 감싸는 데 사용되며, <var>...</var>를 사용하여 표시됩니다. 백쿼트 내의 내용은 문자, 숫자, 밑줄, 붙임표(하이픈), 점만 포함되어야 합니다.

export.show

편집

function export.show(frame)

{{모듈 설명문서}}의 주요 진입점입니다. 프레임 객체는 3개의 선택 인수를 포함할 수 있습니다.

  • |comment_level=: 특정 섹션에서 사용하는 등호(=)의 개수입니다. 기본값은 2로 설정됩니다.(--[==[ ... (주석 블록) ]==])
    예: 값이 4면 --[====[ ... (주석 블록) ]====].
  • |section_level=: 각 함수와 메서드에 사용되는 헤더 레벨입니다. 기본값은 2로 설정됩니다. (예, L2: == ... ==).
  • |identifier=: Lua 문자열 패턴입니다. 이 패턴과 일치하는 함수의 주석만 사용됩니다. 지정하지 않으면 모든 함수가 허락됩니다.
    이는 객체 메서드를 지정할 때 유용하며, ^object_name:과 같은 패턴을 사용합니다.

참고

편집
  • 모든 지역 함수는 외부 모듈에서 보이지 않기 때문에 무시됩니다.
  • 객체 메서드가 지역 함수 내에서 정의된 경우에는 모듈에서 객체가 반환될 수 있으므로 예외적으로 무시되지 않습니다.
  • 주석 내의 중괄호는 syntaxhighlight의 단축키로 사용되며, 그렇지 않으면 syntaxhighlight를 사용할 수 없습니다.

--[===[
이 모듈은 다른 모듈을 위한 설명문서를 자동으로 생성합니다. Lua 코드 내의 인라인 주석을 가져와 {{틀|모듈 설명문서}}
을 통해 설명문서 페이지에 사용할 수 있는 형식으로 변환합니다. 이 모듈의 설명문서는 이 모듈이 작동하는 예시입니다.

설명문서는 모듈 페이지의 맨 위(일반적인 위키텍스트 형태)와 함수 자체 상단(Lua 주석 형태)에 표시되어 있어 이 방식으로
설명문서를 작성하는 데 용이합니다. 각각이 다른 편집 스타일에 적합하며, 이러한 방식으로 두 형태의 코드를 동기화할 수 있습니다.

설명문서 부분은 Lua의 다중 주석 구문({--[==[ ... ]==]})에 의해 구성됩니다. 일반적으로 {{틀|모듈 설명문서}}에 설명
문서를 올바르게 표시하려면 등호가 두 개 필요합니다. 설명문서 내에서는 다음과 같은 규칙을 이용할 수 있습니다.
# 긴 줄(일반 문단 및 목록 항목)은 선택적으로 스페이스나 탭 뒤에 따라오는 새 줄에 의해 개행될 수 있습니다.
  이는 목록에서 raw 주석의 가독성을 높이기 위해 유용한 방법입니다. 이 경우, 새 줄은 공백으로 변환됩니다.
  두 개의 연속된 새 줄을 이용하여 단락을 나눌 수 있습니다.
  raw 주석을 읽기 쉽게 하기 위한 줄 바꿈은 일반적으로 최대 120자 이내에서 이루어지는 것이 권장됩니다.
# 이중 중괄호를 이용한 템플릿 호출은 그대로 삽입되며 확장됩니다.
# 단일 중괄호는 글자 그대로의 텍스트를 둘러싸고, Lua 코드로 구문을 강조 처리하는 데 쓰입니다.
  이 문자열 내의 중첩된 중괄호는 짝이 맞게 배치되어 있다면 올바르게 처리됩니다.
  텍스트 첫 글자가 중괄호인 경우, 앞에 공백을 두면 이를 Lua 구문으로 읽어들이지 않습니다. 끝에는 공백을 넣으면 안 됩니다.
# 백쿼트(`)는 매개변수명을 감싸는 데 사용되며, {<code class="n">...</code>}를 사용하여 표시됩니다.
  백쿼트 내의 내용은 문자, 숫자, 밑줄, 붙임표(하이픈), 점만 포함되어야 합니다. 
# 이중 백쿼트(``)는 대체변수명을 감싸는 데 사용되며, {<var>...</var>}를 사용하여 표시됩니다.
  백쿼트 내의 내용은 문자, 숫자, 밑줄, 붙임표(하이픈), 점만 포함되어야 합니다.
]===]
local m_str_utils = require("Module:string utilities")

local codepoint = m_str_utils.codepoint
local concat = table.concat
local insert = table.insert
local u = m_str_utils.char

local export = {}

local function format_doc(str)
	local code_blocks = {}
	local code_blocks_i = 0
	local private_use_start = 0x100000
	return (str
		 -- {} blocks
		 -- 줄 바꿈 제거를 적용하지 않으려면 이스케이프
		:gsub('%b{}', function(m0)
			if m0:sub(2, 2) == '{' and m0:sub(-2, -2) == '}' then return nil end
			local text = '<syntaxhighlight lang=lua' .. (m0:match'\n' and '' or ' inline') .. '>' .. m0:sub(2, -2):gsub("^ +", "") .. '</syntaxhighlight>'
			code_blocks_i = code_blocks_i + 1
			code_blocks[code_blocks_i] = text
			return u(private_use_start + code_blocks_i)
		end)
    	:gsub("([^\n])\n[ \t]*([^ \t\n#*:;])", "%1 %2") -- 연속된 줄 합치기
    	:gsub("([^\n])\n[ \t]*([^ \t\n#*:;])", "%1 %2") -- 한 문자 줄인 경우 두 번 실행(드문 경우)
		:gsub('\n[ \t]+%f[*#:;]', '\n') -- 리스트 항목의 들여쓰기 제거
		:gsub('%f[\n,{]\n%f[^\n*#:;]', '\n\n') -- 위키 줄바꿈
		:gsub('(\n[ *#:]*)(|?[_%w]+=?):', '%1<code><b>%2</b></code>:') -- 매개변수 이름
		:gsub('``([A-Za-z0-9_%-.]+)``', '<var>%1</var>') -- 이중 백쿼트 사이의 대체 변수
		:gsub('`([A-Za-z0-9_%-.]+)`', '<code class="n">%1</code>') -- 백쿼트 사이의 변수명/매개변수명
		:gsub('\244[\128-\191][\128-\191][\128-\191]', function(char)
			return code_blocks[codepoint(char) - private_use_start]
		end))
end

--[===[
{{틀|모듈 설명문서}}의 주요 진입점입니다. 프레임 객체는 3개의 선택 인수를 포함할 수 있습니다.
* |comment_level=: 특정 섹션에서 사용하는 등호(=)의 개수입니다. 기본값은 2로 설정됩니다.({--[==[ ... (주석 블록) ]==]})
*: 예: 값이 4면 {--[====[ ... (주석 블록) ]====]}.
* |section_level=: 각 함수와 메서드에 사용되는 헤더 레벨입니다. 기본값은 2로 설정됩니다. (예, L2: {== ... ==}).
* |identifier=: Lua 문자열 패턴입니다. 이 패턴과 일치하는 함수의 주석만 사용됩니다. 지정하지 않으면 모든 함수가 허락됩니다.
*: 이는 객체 메서드를 지정할 때 유용하며, {^object_name:}과 같은 패턴을 사용합니다.
]===]
function export.show(frame)
	local args = frame:getParent().args or {}
	
	local comment_level = tonumber(args['comment_level']) or 2
	local pattern_comment = '%-%-%[' .. ('='):rep(comment_level) .. '%[\n?(.-)\n?]' .. ('='):rep(comment_level) .. ']()'
	local section_mark = ('='):rep(tonumber(args['section_level']) or 2)
	local pattern_identifier = args['identifier'] or ''
	
	local mod_title = mw.title.getCurrentTitle()
	if mod_title.text:match'/documentation$' then return '(<i>생성된 설명문서는 모듈 페이지에 위치합니다.</i>)' end
	local mod_text = mod_title:getContent()
	if not mod_text then return '(<i>모듈 문서가 존재하지 않습니다.</i>)' end
	
	local chunk
	
	local leading_section_raw = mod_text:match('^' .. pattern_comment)
	if leading_section_raw then
		chunk = { format_doc(leading_section_raw) }
	else chunk = {} end
	
	for p0, f, fn in mod_text:gmatch('()\n[ \t]*function +(([^\n(]+)[^\n)]+%))') do
		if fn:match(pattern_identifier) then			
			local c = mod_text:sub(1, p0 - 1):match('^.*' .. pattern_comment .. '%s*$')
			insert(chunk, section_mark .. fn .. section_mark .. '\n\n' .. '<syntaxhighlight lang=lua inline>function ' .. f .. '</syntaxhighlight>\n\n' .. format_doc(c or '<strong class="error">이 함수에는 설명문서가 존재하지 않습니다. 함수에 대한 사용법과 입출력, 유사한 함수와의 차이점을 다른 사용자들이 참고할 수 있도록 추가하거나, 함수 목록에서 제거하기 위해 지역 함수로 변경하세요.</strong>[[분류:설명문서가 빠진 모듈과 틀]]'))
		end
	end
	
	local postscriptum = mod_text:match('^.*' .. pattern_comment .. '%s*$')
	if postscriptum then
		insert(chunk, section_mark .. '참고' .. section_mark .. '\n\n' .. format_doc(postscriptum))
	end
	
	return frame:preprocess(concat(chunk, '\n\n'))
end

return export
--[===[
* 모든 지역 함수는 외부 모듈에서 보이지 않기 때문에 무시됩니다.
* 객체 메서드가 지역 함수 내에서 정의된 경우에는 모듈에서 객체가 반환될 수 있으므로 예외적으로 무시되지 않습니다.
* 주석 내의 중괄호는 syntaxhighlight의 단축키로 사용되며, 그렇지 않으면 syntaxhighlight를 사용할 수 없습니다.
]===]