Perl POD 형식 명세와 주석
Perl POD 형식 명세와 주석 (perlpodspec)
POD 마크업 언어에 대한 상세한 주석 문서예요. 대부분의 사람은 POD로 쓰는 법을 알기 위해 perlpod만 읽으면 되지만, 이 문서는 POD를 파싱하고 렌더링하는 데 관한 잔잔한 질문들에 답해줄 수 있어요.
이 문서에서 "must/must not", "should/should not", "may"는 관례적인(RFC 2119 참조) 의미를 가져요. "X must do Y"는 X가 Y를 안 하면 이 명세에 위배되는 것이고, 정말로 고쳐져야 한다는 뜻이에요. "X should do Y"는 권장된다는 뜻이지만, X가 좋은 이유가 있으면 Y를 못 할 수도 있다는 뜻이에요. "X may do Y"는 단순히 X가 마음대로 Y를 할 수 있다는 주석이에요. (다만 "그리고 X가 Y를 하면 좋을 텐데"라는 뉘앙스를 감지할지, 아니면 "X가 Y를 해도 나는 별로 신경 안 쓸 텐데"라는 뉘앙스를 감지할지는 독자의 몫이에요.)
특히 "파서는 Y를 해야 한다(should)"고 말할 때, 호출하는 응용이 명시적으로 파서에게 Y를 하지 말라 고 요청하면 파서는 Y를 못 할 수도 있어요. 나는 흔히 이걸 "파서는 기본적으로 Y를 해야 한다"고 표현해요. 이는 파서가 어떤 기능 Y를 끄는 옵션(예를 들어 verbatim 문단에서 탭 확장)을 제공할 것을 요구 하진 않아요. 다만 그런 옵션이 제공될 수는 있다는 걸 함의하죠.
본문
POD 정의 (Pod Definitions)
POD는 파일에 내장되는데, 보통 Perl 소스 파일이에요. 물론 POD만으로 이뤄진 파일을 쓸 수도 있어요.
파일의 line(줄) 은 0개 이상의 개행이 아닌 문자로 이뤄지며, 개행 또는 파일 끝으로 끝나요.
newline sequence(개행 시퀀스) 는 보통 플랫폼 의존 개념이지만, POD 파서는 CR(ASCII 13), LF(ASCII 10), CRLF(ASCII 13 직후 ASCII 10) 중 어느 것이든, 다른 시스템 고유 의미와 함께, 그렇게 이해해야 해요. 파일의 첫 CR/CRLF/LF 시퀀스가 나머지 파일을 파싱하기 위한 개행 시퀀스를 식별하는 기준으로 쓰일 수 있어요.
blank line(빈 줄) 은 전적으로 0개 이상의 공백(ASCII 32) 또는 탭(ASCII 9)으로 이뤄지고 개행 또는 파일 끝으로 끝나는 줄이에요. non-blank line(비빈 줄) 은 공백이나 탭이 아닌 문자를 하나 이상 포함하는(그리고 개행 또는 파일 끝으로 끝나는) 줄이에요.
(참고: 많은 옛 POD 파서는 공백/탭으로 이뤄지고 개행으로 끝나는 줄을 빈 줄로 받아들이지 않았어요. 그들이 빈 줄로 간주한 것은 문자가 전혀 없는 줄과 개행으로 끝나는 줄뿐이었어요.)
Whitespace(공백) 는 이 문서에서 공백, 탭, 개행 시퀀스의 포괄 용어로 쓰여요. (이 용어 자체는 보통 문자 그대로의 공백을 가리켜요. 즉 POD 소스의 공백 문자 시퀀스 말이에요. 공백 문자를 표기하는 서식 코드인 "E<32>"와는 구별돼요.)
POD 파서(Pod parser) 는 POD를 파싱하기 위한 모듈이에요. (콜백 호출이나 파싱 트리 구축이나 직접 포맷팅을 포함하든 아니든.) POD 포매터(Pod formatter) 또는 POD 번역기(Pod translator) 는 POD를 다른 형식(HTML, plaintext, TeX, PostScript, RTF)으로 변환하는 모듈 또는 프로그램이에요. POD 프로세서(Pod processor) 는 포매터나 번역기일 수도 있고, POD로 다른 일(단어 세기, 인덱스 점 검사 등)을 하는 프로그램일 수도 있어요.
POD 내용은 POD 블록(Pod blocks) 에 담겨요. POD 블록은 m/\A=[a-zA-Z]/와 일치하는 줄로 시작하고, m/\A=cut/와 일치하는 다음 줄까지, 또는 m/\A=cut/ 줄이 없으면 파일 끝까지 이어져요.
파서가 여기 문서 같은 quoted string 안에 있는 POD처럼 보이는 것을 구별할 필요는 없다고 가정해요.
POD 블록 안에는 POD 문단(Pod paragraphs) 이 있어요. POD 문단은 하나 이상의 빈 줄로 구분되는 비빈 텍스트 줄로 이뤄져요.
POD 처리 목적으로, POD 블록에는 네 가지 유형의 문단이 있어요:
-
명령 문단(command paragraph) ("directive"라고도 불려요). 이 문단의 첫 줄은
m/\A=[a-zA-Z]/와 일치해야 해요. 명령 문단은 보통 한 줄이에요. 이렇게요:=head1 NOTES =item *하지만 여러 (비빈) 줄에 걸칠 수도 있어요:
=for comment Hm, I wonder what it would look like if you tried to write a BNF for Pod from this. =head3 Dr. Strangelove, or: How I Learned to Stop Worrying and Love the Bomb일부 명령 문단은 내용(즉
m/\A=[a-zA-Z]\S*\s*/와 일치하는 부분 이후)에 서식 코드를 허용해요. 이렇게요:=head1 Did You Remember to C<use strict;>?즉, "head1"에 대한 POD 처리 핸들러는 "Did You Remember to C<use strict;>?"에, 일반 문단에 적용할 것과 같은 처리를 적용해요. (즉 "C<...>" 같은 서식 코드가 파싱되어 적절히 포맷팅되고, 문자 그대로의 공백·탭 형태의 공백은 유의미하지 않은 것으로 취급돼요.)
-
verbatim 문단(ververbatim paragraph). 이 문단의 첫 줄은 문자 그대로의 공백이나 탭이어야 하고, "identifier "가 콜론(":")으로 시작하지 않는 한 "=begin identifier ", ... "=end identifier " 시퀀스 안에 있으면 안 돼요. 즉, 문단이 문자 그대로의 공백이나 탭으로 시작하지만 "=begin identifier ", ... "=end identifier " 영역 안에 있다면, "identifier "가 콜론으로 시작하지 않는 한 그건 데이터 문단이에요.
verbatim 문단에서는 공백 이 유의미해요. (다만 처리 중 탭은 아마 확장될 거예요.)
-
일반 문단(ordinary paragraph). 문단의 첫 줄이
m/\A=[a-zA-Z]/도m/\A[ \t]/도 일치하지 않고, "identifier "가 콜론(":")으로 시작하지 않는 한 "=begin identifier ", ... "=end identifier " 시퀀스 안에 있지 않으면 그 문단은 일반 문단이에요. -
데이터 문단(data paragraph). "identifier "가 문자 그대로의 콜론(":")으로 시작하지 않는 "=begin identifier " ... "=end identifier " 시퀀스 안에 있는 문단이에요. 어떤 의미에서 데이터 문단은 POD가 전혀 아니에요 (즉 실질적으로 "대역 외(out-of-band)"예요). 대부분의 종류의 POD 파싱 대상이 아니거든요. 하지만 여기 규정되는 이유는 POD 파서가 그것을 위한 이벤트를 호출하거나, 파싱 트리에 어떤 형태로 저장하거나, 적어도 그 주변을 파싱할 수 있어야 하기 때문이에요.
예를 들어 다음 문단들을 고려해볼게요:
# <- that's the 0th column
=head1 Foo
Stuff
$foo->bar
=cut
여기서 "=head1 Foo"와 "=cut"은 각각의 첫 줄이 m/\A=[a-zA-Z]/와 일치하므로 명령 문단이에요. "[space][space] $foo->bar"는 첫 줄이 문자 그대로의 공백 문자로 시작하고 (주변에 "=begin"..."=end" 영역이 없으므로) verbatim 문단이에요.
"identifier "가 콜론으로 시작하지 않으면, "=begin identifier " ... "=end identifier " 명령이 그것이 둘러싼 문단이 일반·verbatim 문단으로 파싱되지 않게 막아요. 이는 "데이터 문단과 '=begin/=end' 영역에 대하여" 절에서 자세히 논의돼요.
POD 명령 (Pod Commands)
이 절은 perlpod의 "Command Paragraph"의 논의를 보충·명확히 하기 위한 것이에요. 현재 인식되는 POD 명령들:
"=head1", "=head2", "=head3", "=head4", "=head5", "=head6"
이 명령은 문단의 나머지 텍스트가 제목(heading)임을 나타내요. 그 텍스트는 서식 코드를 포함할 수 있어요. 예:
=head1 Object Attributes
=head3 What B<Not> to Do!
=head5와 =head6 둘 다 2020년에 추가되었고 모든 POD 파서가 지원하진 않을 수 있어요. Pod::Simple 3.41은 2020년 10월에 릴리스되었고, 이 둘을 지원해 모든 Pod::Simple 기반 POD 파서에 지원을 제공해요.
"=pod"
이 명령은 이 문단이 POD 블록을 시작함을 나타내요. (이미 POD 블록 중간에 있다면 이 명령은 전혀 효과가 없어요.) 이 명령 문단에 "=pod" 뒤에 텍스트가 있으면 무시해야 해요. 예:
=pod
This is a plain Pod paragraph.
=pod This text is ignored.
"=cut"
이 명령은 이 줄이 이전에 시작된 POD 블록의 끝임을 나타내요. 줄에 "=cut" 뒤에 텍스트가 있으면 무시해야 해요. 예:
=cut
=cut The documentation ends here.
=cut
# This is the first line of program text.
sub foo { # This is the second.
"=cut" 명령으로 POD 블록을 시작 하려는 건 오류예요. 그 경우 POD 프로세서는 입력 파일의 파싱을 중단해야 하고, 기본적으로 경고를 내야 해요.
"=over"
이 명령은 목록/들여쓰기 영역의 시작임을 나타내요. "=over" 뒤에 텍스트가 있으면 0이 아닌 양의 숫자만으로 이뤄져야 해요. 이 숫자의 의미는 아래 "=over...=back 영역에 대하여" 절에서 설명해요. 서식 코드는 확장되지 않아요. 예:
=over 3
=over 3.5
=over
"=item"
이 명령은 목록의 항목이 여기서 시작됨을 나타내요. 서식 코드는 처리돼요. 문단 나머지의 (선택적) 텍스트의 의미는 아래 "=over...=back 영역에 대하여" 절에서 설명해요. 예:
=item
=item *
=item *
=item 14
=item 3.
=item C<< $thing->stuff(I<dodad>) >>
=item For transporting us beyond seas to be tried for pretended
offenses
=item He is at this time transporting large armies of foreign
mercenaries to complete the works of death, desolation and
tyranny, already begun with circumstances of cruelty and perfidy
scarcely paralleled in the most barbarous ages, and totally
unworthy the head of a civilized nation.
"=back"
이 명령은 가장 최근 "=over" 명령이 시작한 영역의 끝임을 나타내요. "=back" 명령 뒤에는 텍스트를 허용하지 않아요.
"=begin formatname" / "=begin formatname parameter"
이 명령은 뒤따르는 문단(일치하는 "=end formatname"까지)이 어떤 특별한 종류의 처리를 위한 것임을 표시해요. "formatname"이 콜론으로 시작하지 않으면, 포함된 비명령 문단은 데이터 문단이에요. 하지만 "formatname" 이 콜론으로 시작하면, 비명령 문단은 일반 문단 또는 데이터 문단이에요. 이는 "데이터 문단과 '=begin/=end' 영역에 대하여" 절에서 자세히 논의돼요.
formatname은 정규식 m/\A:?[-a-zA-Z0-9_]+\z/와 일치하길 권장해요. formatname 뒤 공백 다음의 모든 것은 파라미터로, 이 영역을 다룰 때 포매터가 사용할 수 있어요. 이 파라미터는 "=end" 문단에 반복되어선 안 돼요. 구현자는 "=begin"/"=end"/"=for"의 첫 파라미터의 의미·문법의 미래 확장을 예상해야 해요.
"=end formatname"
이 명령은 일치하는 "=begin formatname" 영역이 열어준 영역의 끝을 표시해요. "formatname"이 가장 최근에 열린 "=begin formatname" 영역의 formatname이 아니면, 이는 오류이고 오류 메시지를 생성해야 해요. 이는 "데이터 문단과 '=begin/=end' 영역에 대하여" 절에서 자세히 논의돼요.
"=for formatname text..."
이 명령은 다음의 동의어예요:
=begin formatname
text...
=end formatname
즉, 단일 문단으로 이뤄진 영역을 만들고, "formatname"이 ":"으로 시작하면 그 문단은 일반 문단으로 취급돼요. "formatname" 이 콜론으로 시작하지 않으면 "text..."는 데이터 문단을 구성해요. "=for formatname text..."로 "text..."를 verbatim 문단으로 표현할 방법은 없어요.
"=encoding encodingname"
이 명령은 문서에 일찍 (적어도 어떤 비-ASCII 데이터보다 먼저!) 나타나야 하고, 이 문서가 encodingname 인코딩으로 인코딩됐음을 선언해요. encodingname 은 Encode가 인식하는 인코딩 이름이어야 해요. (Encode의 지원 인코딩 목록은 Encode::Supported에 유용하게 있어요.) POD 파서가 선언된 인코딩을 디코딩할 수 없으면 경고를 내고 문서 파싱을 아예 중단할 수도 있어요.
"=encoding" 줄이 둘 이상 있는 문서는 오류로 간주해야 해요. POD 프로세서는 첫 번째가 아닌 "=encoding" 줄이 첫 번째 것의 단순 복제일 때(예: "=encoding utf8" 줄 뒤 나중에 또 "=encoding utf8" 줄)이면 조용히 허용할 수 있어요. 하지만 같은 문서에 모순된 "=encoding" 줄이 있으면(예: 문서 초반에 "=encoding utf8", 후반에 "=encoding big5") 불평해야 해요. BOM을 인식하는 POD 프로세서는 BOM과 모순되는 "=encoding" 줄을 보면 불평할 수도 있어요 (예: UTF-16LE BOM이 있는 문서에 "=encoding shiftjis" 줄).
POD 프로세서가 위에 나열된 것 외의 다른 명령(예: "=head", "=haed1", "=stuff", "=cuttlefish", "=w123")을 보면, 그 프로세서는 기본적으로 이걸 오류로 취급해야 해요. 그 명령으로 시작하는 문단을 처리하지 말아야 하고, 기본적으로 이걸 오류로 경고하며, 파싱을 중단할 수 있어요. POD 파서는 특정 응용이 위 알려진 명령 목록에 추가하고, 추가 명령 각각에 대해 서식 코드를 처리할지 지정하는 방법을 허용할 수 있어요.
이 명세의 미래 버전은 추가 명령을 더할 수 있어요.
POD 서식 코드 (Pod Formatting Codes)
(이 문서와 perlpod의 이전 초안에서는 서식 코드를 "interior sequences"라고 불렀고, 이 용어는 POD 파서 문서와 POD 프로세서의 오류 메시지에서 여전히 발견될 수 있어요.)
서식 코드에는 두 가지 문법이 있어요:
-
서식 코드는 대문자(US-ASCII [A-Z]만)로 시작하고 이어서 "<" 하나, 임의의 문자 수, 그리고 첫 번째 일치하는 ">"로 끝나요. 예:
That's what I<you> think! What's C<CORE::dump()> for? X<C<chmod> and C<unlink()> Under Different Operating Systems> -
서식 코드는 대문자(US-ASCII [A-Z]만)로 시작하고 이어서 "<" 두 개 이상, 하나 이상의 공백 문자, 임의의 문자 수, 하나 이상의 공백 문자, 그리고 이 서식 코드의 여는 "<"의 개수와 같은 개수의 ">"의 첫 번째 일치 시퀀스로 끝나요. 예:
That's what I<< you >> think! C<<< open(X, ">>thing.dat") || die $! >>> B<< $foo->bar(); >>
이 문법에서 "C<<<" 다음과 ">>>" 앞의 (또는 어떤 글자든) 공백 문자들은 렌더링되지 않아요. 그들은 공백을 나타내지 않고, 단지 서식 코드 자체의 일부일 뿐이에요. 즉 이들은 모두 동의어예요:
C<thing>
C<< thing >>
C<< thing >>
C<<< thing >>>
C<<<<
thing
>>>>
등등.
마지막으로, 다중 꺾쇠 형태는 중첩 서식 코드의 해석을 바꾸지 않아요. 즉 다음 네 예시 줄은 뜻이 동일해요:
B<example: C<$a E<lt>=E<gt> $b>>
B<example: C<< $a <=> $b >>>
B<example: C<< $a E<lt>=E<gt> $b >>>
B<<< example: C<< $a E<lt>=E<gt> $b >> >>>
POD를 파싱할 때 특히 까다로운 부분은 (잠재적으로 중첩된!) 서식 코드를 올바르게 파싱하는 거예요. 구현자는 Pod::Parser의 parse_text 루틴의 코드를 올바른 구현의 예로 참고해야 해요.
I<text> — 이탤릭 텍스트
perlpod의 "Formatting Codes"의 간단한 논의를 참고하세요.
B<text> — 볼드 텍스트
perlpod의 "Formatting Codes"의 간단한 논의를 참고하세요.
U<text> — 밑줄 텍스트
perlpod의 "Formatting Codes"의 간단한 논의를 참고하세요.
이것은 2024년에 추가되었고 모든 POD 파서가 지원하진 않을 수 있어요.
C<code> — 코드 텍스트
perlpod의 "Formatting Codes"의 간단한 논의를 참고하세요.
F<filename> — 파일 이름용 스타일
perlpod의 "Formatting Codes"의 간단한 논의를 참고하세요.
X<topic name> — 색인 항목
perlpod의 "Formatting Codes"의 간단한 논의를 참고하세요.
이 코드는 대부분 포매터가 이 코드와 그 내용을 완전히 버린다는 점에서 특이해요. 다른 포매터는 현재 문서의 색인을 만드는 데 쓰일 수 있는 보이지 않는 코드로 렌더링해요.
Z<> — null(무효과) 서식 코드
perlpod의 "Formatting Codes"에서 간단히 논의돼요.
이 코드는 내용이 없어야 한다는 점에서 특이해요. 즉 프로세서는 Z<potatoes>를 보면 불평할 수 있어요. 불평하든 안 하든, potatoes 텍스트는 무시해야 해요.
L<name> — 하이퍼링크
이 코드의 복잡한 문법은 perlpod의 "Formatting Codes"에서 길게 논의되고, 구현 세부 사항은 아래 "L<...> 코드에 대하여"에서 논의돼요. L
E<escape> — 문자 이스케이프
perlpod의 "Formatting Codes"와 "POD 프로세서 구현에 관한 주석"의 여러 지점을 참고하세요.
S<text> — 텍스트가 줄바꿈 없는 공백을 포함
이 서식 코드는 문법적으로는 단순하지만 의미적으로는 복잡해요. 그 뜻은 이 코드의 인쇄 가능한 내용의 각 공백이 줄바꿈 없는 공백(non-breaking space)을 나타낸다는 거예요.
고려해볼게요:
C<$x ? $y : $z>
S<C<$x ? $y : $z>>
둘 다 "$x", 공백 하나, "?", 공백 하나, ":", 공백 하나, "$z"로 이뤄진 고정폭(c[ode] 스타일) 텍스트를 나타내요. 차이는 후자에서 S 코드로 인해 그 공백들이 "정상" 공백이 아니라 줄바꿈 없는 공백이라는 거예요.
POD 프로세서가 위에 나열된 것 외의 다른 서식 코드("N<...>", "Q<...>" 등)를 보면, 그 프로세서는 기본적으로 이걸 오류로 취급해야 해요. POD 파서는 특정 응용이 위 알려진 서식 코드 목록에 추가하는 방법을 허용할 수 있어요. POD 파서는 추가 명령 각각에 L<...>이 하듯 어떤 형태의 특수 처리를 요구하는지 지정하는 방법조차 허용할 수 있어요.
이 명세의 미래 버전은 추가 서식 코드를 더할 수 있어요.
역사적 참고: 몇몇 오래된 POD 프로세서는 ">" 바로 앞에 "-"가 있으면 그 ">"를 "C<" 코드의 닫음으로 보지 않았어요. 이는 다음이:
C<$foo->bar>
다음과 동치로 파싱되도록 하기 위함이었어요:
C<$foo-E<gt>bar>
"$foo-"만 포함하는 "C" 서식 코드에, 그 다음 "C" 서식 코드 밖에 "bar>"가 있는 것으로 파싱되는 대신요. 이 문제는 이후 다음 같은 문법 추가로 해결되었어요:
C<< $foo->bar >>
규격을 따르는 파서는 "->"를 특수하게 취급해서는 안 돼요.
서식 코드는 절대 문단을 가로지를 수 없어요. 코드가 한 문단에서 열렸고 그 문단 끝까지 닫는 코드가 없으면, POD 파서는 그 서식 코드를 닫아야 하고 불평해야 해요 (예: "line 123에서 시작하는 문단의 종료되지 않은 I 코드: 'Time objects are not...'"). 그래서 이 두 문단은:
I<I told you not to do this!
Don't make me say it again!>
...이탤릭의 두 문단으로 파싱되면 안 돼요. (I 코드가 한 문단에서 시작해 다른 문단에서 끝나며.) 대신 첫 문단은 경고를 생성해야 하지만, 그걸 제외하면 위 코드는 마치 다음과 같이 파싱되어야 해요:
I<I told you not to do this!>
Don't make me say it again!E<gt>
(SGMLish 용어로, 모든 POD 명령은 블록 수준 요소 같은 것이고, 모든 POD 서식 코드는 인라인 수준 요소 같은 것이에요.)
POD 프로세서 구현에 관한 주석 (Notes on Implementing Pod Processors)
다음은 POD 처리에 관한 잡다한 요구사항과 제안의 긴 절이에요.
-
POD 포매터는 verbatim 블록의 어떤 길이의 줄이든 참아야 해요. 텍스트가 페이지 옆으로 흘러넘치지 않게 (매우 긴 줄은 어쩌면 여러 번) 줄을 끊어야 하더라도요. POD 포매터는 그런 줄바꿈에 대해 경고할 수 있어요. 그런 경고는 특히 100자 이상인 줄에 적절한데, 그런 줄은 보통 의도적이지 않거든요.
-
POD 파서는 잘 알려진 세 가지 개행 형식 CR, LF, CRLF를 모두 인식해야 해요. perlport를 참고하세요.
-
POD 파서는 어떤 길이의 입력 줄이든 받아들여야 해요.
-
Perl이 파일 시작의 유니코드 BOM(Byte Order Mark)을 그 파일이 UTF-16(빅엔디언이든 리틀엔디언이든)이나 UTF-8로 유니코드 인코딩됐다는 신호로 인식하므로, POD 파서도 그렇게 해야 해요. 그렇지 않으면, 파일의 첫 상위비트(highbit) 바이트 시퀀스가 UTF-8 시퀀스로 유효해 보이면 문자 인코딩은 UTF-8로 이해되어야 하고, 그렇지 않으면 CP-1252로 이해되어야 해요. (이 명세의 이전 버전은 CP-1252 대신 Latin-1을 썼어요.)
이 명세의 미래 버전은 POD가 다른 인코딩을 받아들이는 방법을 규정할 수 있어요. 아마 POD 파싱에서 다른 인코딩 처리는 XML 파싱처럼 될 거예요. 특정 POD 파일이 선언한 인코딩이 무엇이든 내용은 메모리에 유니코드 문자로 저장되는 거죠.
-
잘 알려진 유니코드 BOM은 다음과 같아요. 파일이 두 개의 문자 그대로의 바이트 값 0xFE 0xFF로 시작하면 이건 빅엔디언 UTF-16의 BOM이에요. 파일이 두 개의 문자 그대로의 바이트 0xFF 0xFE로 시작하면 이건 리틀엔디언 UTF-16의 BOM이에요. ASCII 플랫폼에서 파일이 세 개의 문자 그대로의 바이트 0xEF 0xBB 0xBF로 시작하면 이건 UTF-8의 BOM이에요. EBCDIC 플랫폼에 이식 가능한 메커니즘은:
my $utf8_bom = "\x{FEFF}"; utf8::encode($utf8_bom); -
ASCII 플랫폼에서 BOM 없는 파일(코드든 POD든!)의 첫 상위비트 바이트 시퀀스를 검사해 그 시퀀스가 UTF-8(RFC 2279)로 유효한지 보는 순진하지만 자주 충분한 휴리스틱은, 시퀀스의 첫 바이트가 0xC2
0xFD 범위에 있고 다음 바이트가 0x800xBF 범위에 있는지 확인하는 거예요. 그렇다면 파서는 이 파일이 UTF-8이라고 결론내리고, 파일의 모든 상위비트 시퀀스가 UTF-8이라고 가정해야 해요. 그렇지 않으면 파서는 파일을 CP-1252로 취급해야 해요. (더 나은 검사는, EBCDIC 플랫폼에서도 동작하는데, 시퀀스의 복사본을 utf8::decode()에 넘기는 거예요. 이 함수는 시퀀스에 완전한 유효성 검사를 수행하고 유효한 UTF-8이면 TRUE, 아니면 FALSE를 돌려줘요. 이 함수는 항상 사전 로드되고 C로 쓰여서 빠르며, 기껏해야 한 번만 호출되므로 성능 우려로 피할 필요가 없어요.) 진짜 비-UTF-8 파일의 첫 상위비트 시퀀스가 우연히 UTF-8처럼 보이는 드문 상황에서는, 우리 휴리스틱(그리고 더 영리한 휴리스틱)에 대비해 그 줄 앞에 UTF-8로는 분명히 유효하지 않은 상위비트 시퀀스를 담은 주석 줄을 붙일 수 있어요. 그냥 "#", e-acute, 그리고 어떤 비상위비트 바이트로 이뤄진 줄이면 이 파일의 인코딩을 확립하기에 충분해요. -
POD 프로세서는 "=for [label] [content...]" 문단을 "=begin [label]" 문단, 내용, "=end [label]" 문단과 같은 뜻으로 취급해야 해요. (파서는 이 두 구조를 합칠 수도, 구별해 둘 수도 있어요. 포매터가 어쨌든 같게 취급할 것이라고 기대하며요.)
-
POD를 주석을 허용하는 형식(즉 거의 평문을 제외한 모든 형식)으로 렌더링할 때, POD 포매터는 그 이름과 버전 번호, 그리고 POD를 처리하는 데 쓸 수 있는 모듈들의 이름과 버전 번호를 식별하는 주석 텍스트를 삽입해야 해요. 최소 예:
%% POD::Pod2PS v3.14159, using POD::Parser v1.92 <!-- Pod::HTML v3.14159, using POD::Parser v1.92 --> {\doccomm generated by Pod::Tree::RTF 3.14159 using Pod::Tree 1.08} .\\" Pod::Man version 3.14159, using POD::Parser version 1.92포매터는 POD 포매터 프로그램의 릴리스 날짜, 포매터 저자의 연락 주소, 현재 시간, 입력 파일 이름, 적용 중인 포매팅 옵션, 쓰인 Perl 버전 등을 포함한 추가 주석을 삽입할 수도 있어요.
포매터는 오류/경고를 (다른 방식으로 내는 대신 또는 그와 더불어) 주석으로 기록하기로 선택할 수도 있어요. (STDERR로 메시지나
die하는 것처럼.) -
POD 파서는 STDERR로 경고나 오류 메시지("알 수 없는 E 코드 E
!")를 (STDERR로 출력하거나, warning/carping, 또는dieing/croaking으로) 내 수도 있지만, 그런 모든 STDERR 출력을 억제하고 대신 콜백 트리거, 문서 객체의 어떤 속성의 오류 기록, 또는 유사하게 눈에 거슬리지 않는 메커니즘 — 심지어 문서의 파싱된 형태 끝에 "Pod Errors" 절을 추가하는 — 으로 오류/경고를 보고할 옵션을 허용 해야 해요. -
과도하게 변칙적인 문서의 경우 POD 파서는 파싱을 중단할 수 있어요. 그때조차
dieing/croaking을 쓰는 건 피해야 해요. 가능하면 파서 라이브러리는 입력 파일을 닫고 "(부분) 메모리 내 문서" 끝에 "*** Formatting Aborted ***" 같은 텍스트를 추가하면 돼요. -
서식 코드(E<...>, B<...> 등)가 이해되는 문단(즉 아닌 verbatim 문단이지만, 일반 문단과 렌더링 가능한 텍스트를 만드는 "=head1" 같은 명령 문단 을 포함하는)에서, 문자 그대로의 공백은 일반적으로 "유의미하지 않은" 것으로 간주해야 해요. 하나의 문자 그대로 공백이 어떤 (0이 아닌) 수의 문자 그대로 공백, 문자 그대로 개행, 문자 그대로 탭과 같은 의미를 갖기 때문이에요. (문단을 끝내는 빈 줄을 만들지 않는 한.) POD 파서는 처리된 각 문단의 문자 그대로 공백을 압축해야 하지만, 이를 덮어쓰는 옵션을 제공할 수도 있고(일부 처리 작업은 요구하지 않으므로), 추가 특별 규칙을 따를 수도 있어요. (예: 마침표-공백-공백 또는 마침표-개행 시퀀스를 특별 취급.)
-
POD 파서는 기본적으로 아포스트로피(')와 인용부호(")를 스마트 쿼트(작은 9, 66, 99 등)로 강제하거나, 백틱(`)을 백틱 문자 하나(여는 인용부호 문자와 구별되는!) 외의 것으로 바꾸거나, "--"를 두 개의 마이너스 부호 외의 것으로 바꾸려 하지 말아야 해요. C<...> 서식 코드의 텍스트에는 그 어떤 것도 절대 하면 안 되고, verbatim 문단의 텍스트에는 절대, 절대 하면 안 돼요.
-
POD를 두 종류의 하이픈(-)이 있는 형식으로 렌더링할 때, 하나는 줄바꿈 없는 하이픈이고 다른 하나는 줄바꿈 가능한 하이픈("object-oriented"처럼 "object-", 개행, "oriented"로 줄을 나눌 수 있는)일 때, 포매터는 일반적으로 "-"를 줄바꿈 없는 하이픈으로 번역하도록 권장되지만, 이 중 일부를 줄바꿈 가능한 하이픈으로 변환하는 휴리스틱을 적용할 수도 있어요.
-
POD 포매터는 Perl 코드의 단어가 줄을 가로질러 끊기지 않도록 합리적인 노력을 해야 해요. 예를 들어 어떤 포매팅 시스템에서 "Foo::Bar"는 "Foo::" 개행 "Bar" 또는 심지어 "Foo::-" 개행 "Bar"로 줄을 나눌 자격이 있는 것으로 보여요. 가능하면 이를 피해야 해요. 중간 단어의 모든 줄바꿈을 비활성화하거나, 내부 구두점이 있는 특정 단어를 "이걸 줄에 걸쳐 끊지 마" 코드로 감싸거나. (어떤 형식에서는 단일 코드가 아니라, 단어의 모든 문자 쌍 사이에 줄바꿈 없는 0폭 공백을 넣는 문제일 수 있어요.)
-
POD 파서는 기본적으로 verbatim 문단의 탭을 처리하면서, 포매터나 다른 프로세서에 넘기기 전에 확장해야 해요. 파서는 이를 덮어쓰는 옵션도 허용할 수 있어요.
-
POD 파서는 기본적으로 일반·verbatim 문단 끝의 개행을 제거한 뒤 포매터에 넘겨야 해요. 예를 들어 지금 읽고 있는 문단은 POD 소스에서 (그것을 끝내는 개행(들)로) 끝나고 포함한다고 생각할 수 있지만, 이 문장을 끝내는 마침표 문자로 끝나고 포함하도록 처리되어야 해요.
-
POD 파서는 오류를 보고할 때, 단지 문단 번호를 기록하는 대신 근사 줄 번호를 보고하려고 노력해야 해요 ("Thing/Foo.pm의 633줄 근처 문단 #52의 중첩 E<>'s!"). 여기가 문제가 될 때는, 문단 번호에 최소한 문단 발췌를 동반해야 해요 ("'Read/write accessor for the C
attribute...'로 시작하는 Thing/Foo.pm의 문단 #52의 중첩 E<>'s"). -
POD 파서는 일련의 verbatim 문단을 연달아 처리할 때, 그것들이 빈 줄을 포함하는 하나의 큰 verbatim 문단이라고 간주해야 해요. 즉 빈 줄이 사이에 있는 이 두 줄은:
use Foo; print Foo->VERSION포매터나 다른 프로세서에 넘기기 전에 하나의 문단("\tuse Foo;\n\n\tprint Foo->VERSION")으로 통합되어야 해요. 파서는 이를 덮어쓰는 옵션도 허용할 수 있어요.
이건 이벤트 기반 POD 파서에서 구현하기엔 너무 번거로울 수 있지만, 파싱 트리를 돌려주는 파서에는 간단해요.
-
POD 포매터는 가능하면 짧은 verbatim 문단(대략 12줄 미만)이 페이지를 가로지르는 것을 피하도록 권장돼요.
-
POD 파서는 공백과/또는 탭만 있는 줄을 문단을 구분하는 "빈 줄"로 취급해야 해요. (일부 옛 파서는 두 개의 인접한 개행만 "빈 줄"로 인식하고, 개행, 공백, 개행은 빈 줄로 인식하지 않았어요. 이건 규격 위반 행동이에요.)
-
POD 포매터/프로세서의 저자는 자신만의 POD 파서를 쓰는 것을 최대한 피해야 해요. CPAN에 이미 인터페이스 스타일이 다양한 여러 개가 있고, 그 중 하나인 Pod::Simple은 최신 Perl과 함께 온답니다.
-
POD 문서의 문자는 리터럴로 또는 E
코드의 숫자로 또는 동등한 니모닉으로 전달될 수 있어요. 예를 들어 E 는 E<233>과 정확히 동등해요. 숫자는 EBCDIC 플랫폼에서도 Latin1/Unicode 값이에요. E
숫자 코드로 문자를 참조할 때, 32-126 범위의 숫자는 잘 알려진 US-ASCII 문자를 가리켜요 (유니코드에서도 같은 의미로 거기 정의됨). 모든 POD 포매터는 이를 충실히 렌더링해야 해요. E<> 숫자가 0-31과 127-159 범위인 문자는 개행(ASCII 13, ASCII 13 10, ASCII 10)과 탭(ASCII 9)의 문자 그대로의 바이트 시퀀스를 제외하고 (리터럴로도 E 코드로도) 사용해선 안 돼요. 160-255 범위의 숫자는 Latin-1 문자를 가리켜요 (유니코드에서도 같은 의미로 거기 정의됨). 255 위의 숫자는 유니코드 문자를 가리키는 것으로 이해해야 해요.
-
일부 포매터는 32-126 밖의 문자를 안정적으로 렌더링할 수 없다는 점을 경고할게요. 그리고 많은 포매터는 32-126과 160-255를 다룰 수 있지만, 255 위는 다룰 수 없어요.
-
잘 알려진 보다 작음·보다 큼용 "E
"와 "E " 코드 외에도, POD 파서는 "/"(solidus, slash)용 "E "과 "|"(vertical bar, pipe)용 "E "를 이해해야 해요. POD 파서는 문자 171과 187용 레거시 코드로서 "E "과 "E "도 이해해야 해요. 즉 "왼쪽 가리키는 이중 꺾쇠 인용부호" = "왼쪽 가리키는 guillemet"와 "오른쪽 가리키는 이중 꺾쇠 인용부호" = "오른쪽 가리키는 guillemet"예요. (이들은 작은 "<<"와 ">>"처럼 보이고, 지금은 HTML/XHTML 코드 "E "와 "E "로 표현하는 게 바람직해요.) -
POD 파서는
www.W3.org의 가장 최신 XHTML 명세의 엔티티 선언에 정의된 모든 "E" 코드를 이해해야 해요. POD 파서는 최소한 160-255 범위(Latin-1)의 문자를 정의하는 엔티티를 이해해야 해요. POD 파서는 어떤 알 수 없는 "E<identifier >" 코드에 직면하면, (적어도 기본적으로는) 그것을 단순히 null 문자열로 바꿔선 안 되고, 문자 그대로 E, 보다 작음, identifier , 보다 큼 문자로 이뤄진 문자열로 통과시킬 수 있어요. 또는 POD 파서는 그런 알 수 없는 "E<identifier >" 코드를 특별히 위한 이벤트를 발화하거나 메모리 내 문서 트리에 특수 노드 유형을 추가하는 대안 옵션을 제공할 수 있어요. 그런 "E<identifier >"는 일부 프로세서에 특별한 의미를 가질 수 있고, 일부 프로세서는 이를 특수 오류 보고서에 추가하기로 선택할 수 있어요. -
POD 파서는 XHTML 코드 "E
"(문자 34, 큰따옴표 "), "E "(문자 38, 앰퍼샌드 &), "E "(문자 39, 아포스트로피 ')도 지원해야 해요. -
"E
"의 모든 경우에서 whatever(htmlname이든 어떤 밑의 숫자든)는 영숫자 문자만으로 이뤄져야 한다는 점을 주의하세요. 즉 whatever 는 m/\A\w+\z/와 일치해야 해요. 그래서 "E< 0 1 2 3 >"은 공백을 포함하므로 유효하지 않아요. 영숫자 문자가 아니거든요. 이건 아마 POD 프로세서의 특별 처리가 필요하지 않아요. " 0 1 2 3 "은 어떤 밑의 숫자처럼 보이지 않으므로, HTML 유사 이름 표에서 찾아볼 거예요. " 0 1 2 3 "이라는 HTML 유사 엔티티가 없으므로(있을 수도 없고), 이는 오류로 취급될 거예요. 하지만 POD 프로세서는 "E< 0 1 2 3 >"이나 "E"을 문법적으로 유효하지 않은 것으로 취급할 수 있고, 단순히 알 수 없는 (하지만 이론상 유효한) htmlname, 예를 들어 "E " [sic]이 생성하는 오류 메시지(또는 경고나 이벤트)와 다른 오류 메시지를 받을 수 있어요. 하지만 POD 파서가 이 구별을 할 필요는 없어요. -
E
는 "현재/네이티브 문자셋의 코드포인트 number "로 해석하면 안 된다는 점을 주의하세요. 항상 "유니코드의 코드포인트 number 가 나타내는 문자"만을 뜻해요. (이것은 XML의 &#number; 의미와 동일해요.)
이것은 많은 포매터가, 처리 가능한 유니코드 코드포인트(예: e-acute 문자용 "\xE9")에서 대상 출력 형식으로 그런 시퀀스를 전달하는 데 필요한 이스케이프 시퀀스나 코드로의 매핑 테이블을 가질 것을 요구할 거예요. roff로 변환하는 변환기는 예를 들어 "\xE9"(리터럴로든 E<...> 시퀀스로든 전달됐든)가 "e\\'"로 전달돼야 함을 알 거예요. 마찬가지로, Mac OS 응용 창에서 Pod를 렌더링하는 프로그램은 "(이 글을 쓰는 시점에) Mac OS에 네이티브인 MacRoman 인코딩에서 "\xE9"가 코드포인트 142로 매핑됨"을 알아야 할 거예요. 그런 Unicode2whatever 매핑은 흔한 출력 형식에 이미 널리 존재할 거예요. (그런 매핑은 불완전할 수 있어요! 구현자가 체로키 음절 문자, 에트루리아 룬, 비잔틴 음악 기호, 또는 유니코드가 인코딩할 수 있는 다른 이상한 것들을 렌더링하려고 몸을 구부릴 필요는 없어요.) 그리고 POD 문서가 그런 매핑에 없는 문자를 사용하면, 포매터는 그것을 렌더링 불가 문자로 간주해야 해요.
-
놀랍게도 POD 포매터 구현자가 대상 형식의 이스케이프로 유니코드 문자를 매핑하는 만족스러운 기존 테이블(예: *roff 이스케이프로의 괜찮은 유니코드 문자 테이블)을 찾지 못한다면, 그런 테이블을 구축할 필요가 있을 거예요. 이 상황이라면 0x00A0~0x00FF 범위의 문자로 시작해야 해요. 이건 대부분 많이 쓰이는 악센트 문자예요. 그런 다음 (인내가 허용하고 꼼꼼함이 강요하는 대로) (X)HTML 표준 그룹이 니모닉을 부여할 만큼 중요하다고 판단한 문자들을 진행해요. 이들은 www.W3.org 사이트의 (X)HTML 명세에 선언되어 있어요. (2001년 9월 기준) 가장 최신 엔티티 선언 파일은:
http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent그런 다음 0x2000-0x204D 범위의 남은 주목할 만한 유니코드 문자(www.unicode.org의 문자 테이블 참조)와 마음에 드는 것을 진행할 수 있어요. 예를 들어 xhtml-symbol.ent 에는 항목이 있어요:
<!ENTITY infin "∞"> <!-- infinity, U+221E ISOtech -->"infin"을 문자 "\x{221E}"에 매핑하는 건 (바라건대) 이미 POD 파서가 처리했겠지만, 이 문자 파일의 존재는 상당히 중요해서 포매터의 주목할 만한 유니코드 문자를 렌더링에 필요한 코드로 매핑하는 테이블에 포함할 가치가 있음을 뜻해요. 그래서 예를 들어 유니코드-to-*roff 매핑에는 이 항목이 가치 있을 거예요:
"\x{221E}" => '\(in',미래에는 점점 더 많은 형식(과 포매터)이 유니코드 문자를 직접 지원((X)HTML이
∞,∞,∞로 하는 것처럼)하길 간절히 바라요. 그러면 유니코드-to-myescapes 의 특이한 매핑 필요성이 줄어들 거예요. -
렌더링 불가 문자(파서가 렌더링 가능 여부와 무관하게 어떤 것으로도 해결할 수 없었던 알 수 없는 E
시퀀스와는 구별되는)에 직면했을 때는 개별 POD 포매터가 좋은 판단을 보이는 게 몫이에요. 발음 구별 부호가 있는 라틴 문자(예: "E "/"E<233>")를 대응하는 발음 구별 부호 없는 US-ASCII 문자(예: 단순 문자 101, "e")에 매핑하는 것은 좋은 관행이지만, 분명히 종종 실행 불가능하고, 렌더링 불가 문자는 "?" 등으로 표현될 수 있어요. (E<233>에서 "e"로의) 합리적 폴백을 시도할 때, POD 포매터는 Pod::Escapes의 %Latin1Code_to_fallback 테이블이나, 가능하면 Text::Unidecode를 쓸 수 있어요. 예를 들어 이 POD 텍스트:
magic is enabled if you set C<$Currency> to 'E<euro>'.이렇게 렌더링될 수 있어요: "magic is enabled if you set
$Currencyto '? '" 또는 "magic is enabled if you set$Currencyto '[euro] '" 또는 "magic is enabled if you set$Currencyto '[x20AC]'" 등.POD 포매터는 주석이나 경고에서 어떤 렌더링 불가 문자가 마주쳤는지 목록을 기록할 수도 있어요.
-
E<...>는 다른 E<...>나 Z<> 안이 아닌, 어떤 서식 코드에도 자유롭게 나타날 수 있어요. 즉 "X<The E
1,000,000 Solution>"도 유효하고 "L<The E 1,000,000 Solution|Million::Euros>"도 유효해요. -
일부 POD 포매터는 개별 문자로 줄바꿈 없는 공백을 구현하는 형식으로 출력하고(NBSP라고 부를게요), 다른 것은 줄바꿈 없는 공백을 그냥 "이걸 줄에 걸쳐 끊지 마" 코드로 감싼 공백으로 구현하는 형식으로 출력해요. POD 수준에서는 두 종류의 코드 모두 발생할 수 있다는 걸 주의하세요. POD는 NBSP 문자(리터럴로든 "E<160>"이나 "E
" 코드로든)를 포함할 수 있고, POD는 "S<foo I baz>" 코드를 포함할 수 있는데, 그런 코드의 "그저 공백"(문자 32)이 줄바꿈 없는 공백을 나타내는 것으로 받아들여져요. POD 파서는 "S<foo I baz>"가 마치 "foo NBSP I NBSP baz"인 것처럼 선택적으로 파싱하는 것을 고려해야 하고, 반대로 NBSP로 연결된 단어 그룹을 각 그룹이 S<...> 코드 안에 있는 것처럼 선택적으로 파싱하는 것을 고려해야 해요. 그래서 포매터가 출력 형식이 요구하는 것에 가장 잘 매핑되는 표현을 쓸 수 있게 말이에요. -
일부 프로세서는 S 코드의 내용 아래 파싱 트리의 각 공백을 NBSP로 바꾸는 것이 S<...> 코드를 가장 쉽게 구현하는 것임을 발견할 수 있어요. 하지만 주의: 그 교체는 모든 텍스트의 공백에 적용되는 게 아니라, 오직 인쇄 가능한 텍스트의 공백에만 적용되어야 해요. (이 구별은 POD 파서가 구현한 특정 트리/이벤트 모델에서 분명할 수도 있고 아닐 수도 있어요.) 예를 들어 이 특이한 경우를 고려해볼게요:
S<L</Autoloaded Functions>>이건 보이는 링크 텍스트 중간의 공백이 줄을 가로질러 끊기면 안 된다는 뜻이에요. 즉 이와 같아요:
L<"AutoloadedE<160>Functions"/Autoloaded Functions>하지만 잘못 적용된 공백-to-NBSP 교체는 (틀리게) 이와 동등한 것을 만들 수 있어요:
L<"AutoloadedE<160>Functions"/AutoloadedE<160>Functions>...이건 거의 확실히 하이퍼링크로 작동하지 않을 거예요. (이 포매터가 하이퍼텍스트를 지원하는 형식으로 출력한다고 가정할 때.)
포매터는 특히 출력 형식에 NBSP 문자/코드와 "이걸 줄에 걸쳐 끊지 마" 코드가 전혀 없을 때, S 서식 코드를 그냥 지원하지 않기로 선택할 수 있어요.
-
위에서 논의한 NBSP 문자 외에도, 구현자에게 Latin-1의 다른 "특수" 문자인 "soft hyphen"(소프트 하이픈) 문자의 존재를 상기시켜요. "discretionary hyphen"(임의 하이픈)이라고도 불러요. 즉
E<173>=E<0xAD>=E<shy>)예요. 이 문자는 선택적 하이픈 넣기 지점을 표현해요. 즉 보통은 아무것도 렌더링하지 않지만, 포매터가 그 지점에서 단어를 끊으면 "-"로 렌더링될 수 있어요. POD 포매터는 적절히 다음 중 하나를 해야 해요: 1) 같은 의미의 코드(예: RTF의 "\-")로 렌더링, 2) 포매터가 이 문자를 그런 것으로 이해하기를 기대하며 통과, 또는 3) 삭제.예를 들어:
sigE<shy>action manuE<shy>script JarkE<shy>ko HieE<shy>taE<shy>nieE<shy>mi이들은 포매터에게 "sigaction"이나 "manuscript"를 하이픈 넣는다면 "sig-[linebreak] action"이나 "manu-[linebreak] script"로 해야 한다고 신호해요. (그리고 하이픈 넣지 않으면
E<shy>는 전혀 나타나지 않아요.) 그리고 "Jarkko"와/또는 "Hietaniemi"를 하이픈 넣는다면E<shy>코드가 있는 지점에서만 그렇게 할 수 있어요.실제로 이 문자는 자주 쓰이지 않을 것으로 예상되지만, 포매터는 지원하거나 삭제해야 해요.
-
POD에 새 명령을 추가하고 싶다면(예: "=biblio" 명령), for나 begin/end 시퀀스로 같은 효과를 얻을 수 있는지 고려해볼게요: "=for biblio ..." 또는 "=begin biblio" ... "=end biblio". "=for biblio" 등을 이해하지 못하는 POD 프로세서는 그냥 무시할 거예요. 반면 "=biblio"를 보면 크게 불평할 수 있어요.
-
이 문서 전반에서 "Pod"가 문서화 형식 이름의 선호 맞춤법이에요. "POD"나 "pod"를 써도 돼요. (보통) POD 형식인 문서를 위해 "pod", "Pod", "POD"를 쓸 수 있어요. 이 구별을 이해하는 건 유용하지만, 어떻게 철자할지에 집착하는 건 보통 아닙니다.
L<...> 코드에 대하여 (About L<...> Codes)
perlpod를 한눈에 보면 알 수 있듯 L<...> 코드는 POD 서식 코드 중 가장 복잡해요. 아래 관점들이 그것이 무엇을 뜻하는지, 프로세서가 어떻게 다뤄야 하는지 명확히 해줄 거예요.
-
L<...> 코드를 파싱할 때 POD 파서는 최소한 네 가지 속성을 구별해야 해요:
첫째: 링크 텍스트. 없으면
undef여야 해요. (예: "L<Perl Functions|perlfunc>"에서 링크 텍스트는 "Perl Functions"이에요. "LTime::HiRes"와 심지어 "L<|Time::HiRes>"에는 링크 텍스트가 없어요. 링크 텍스트는 포매팅을 포함할 수 있다는 점을 주의하세요.)둘째: 추론될 수 있는 링크 텍스트. 즉 실제 링크 텍스트가 없었다면, 그 자리에 추론할 텍스트예요. (예: "LGetopt::Std"에 대해 추론된 링크 텍스트는 "Getopt::Std"이에요.)
셋째: 이름 또는 URL. 없으면
undef. (예: "L<Perl Functions|perlfunc>"에서 이름은 (page라고도 불려요) "perlfunc"이에요. "L"에서 이름은undef예요.)넷째: 섹션(옛 perlpod의 "item"이라고도 함). 없으면
undef. 예: "LGetopt::Std/DESCRIPTION"에서 "DESCRIPTION"이 섹션이에요. ("man 5 crontab"의 "5" 같은 맨페이지 섹션과는 다른 것이라는 점을 주의하세요. POD 의미의 "Section Foo"는 텍스트가 "Foo"인 제목이나 항목이 소개한 텍스트 부분을 뜻해요.)POD 파서는 다음을 포함한 추가 속성도 기록할 수 있어요:
다섯째: 항목 3(있으면)이 URL("http://lists.perl.org"처럼)인지, POD 이름("perldoc"과 "Getopt::Std"처럼)인지, 어쩌면 맨페이지 이름("crontab(5)"처럼)인지에 대한 플래그. URL이면 섹션 속성이 없어야 해요.
여섯째: 텍스트가 "|", "/" 등으로 분할되기 전, E<...> 코드가 확장되기 전의 원시 원본 L<...> 내용.
(위는 아래에서 간결히 참조하기 위해 번호만 매긴 거예요. 실제 목록이나 배열로 넘겨야 하는 요구사항은 아니에요.)
예를 들어:
L<Foo::Bar> => undef, # link text "Foo::Bar", # possibly inferred link text "Foo::Bar", # name undef, # section 'pod', # what sort of link "Foo::Bar" # original content L<Perlport's section on NL's|perlport/Newlines> => "Perlport's section on NL's", # link text "Perlport's section on NL's", # possibly inferred link text "perlport", # name "Newlines", # section 'pod', # what sort of link "Perlport's section on NL's|perlport/Newlines" # original content L<perlport/Newlines> => undef, # link text '"Newlines" in perlport', # possibly inferred link text "perlport", # name "Newlines", # section 'pod', # what sort of link "perlport/Newlines" # original content L<crontab(5)/"DESCRIPTION"> => undef, # link text '"DESCRIPTION" in crontab(5)', # possibly inferred link text "crontab(5)", # name "DESCRIPTION", # section 'man', # what sort of link 'crontab(5)/"DESCRIPTION"' # original content L</Object Attributes> => undef, # link text '"Object Attributes"', # possibly inferred link text undef, # name "Object Attributes", # section 'pod', # what sort of link "/Object Attributes" # original content L<https://www.perl.org/> => undef, # link text "https://www.perl.org/", # possibly inferred link text "https://www.perl.org/", # name undef, # section 'url', # what sort of link "https://www.perl.org/" # original content L<Perl.org|https://www.perl.org/> => "Perl.org", # link text "https://www.perl.org/", # possibly inferred link text "https://www.perl.org/", # name undef, # section 'url', # what sort of link "Perl.org|https://www.perl.org/" # original contentURL 링크는
m/\A\w+:[^:\s]\S*\z/와 일치한다는 사실로 다른 것과 구별할 수 있다는 점을 주의하세요. 그래서L<http://www.perl.com>은 URL이지만,L<HTTP::Response>는 아니에요. -
"text|" 부분이 없는 L<...> 코드의 경우, 옛 포매터들은 링크나 상호참조를 실제로 표시하는 데 큰 차이를 보였어요. 예를 들어 L<crontab(5)>는 "the
crontab(5)manpage", "in thecrontab(5)manpage", 또는 그냥 "crontab(5)"로 렌더링했어요.POD 프로세서는 이제 "text|" 없는 링크를 다음과 같이 취급해야 해요:
L<name> => L<name|name> L</section> => L<"section"|/section> L<name/section> => L<"section" in name|name/section> -
섹션 이름이 마크업을 포함할 수 있다는 점을 주의하세요. 즉 섹션이 이렇게 시작하면:
=head2 About the C<-M> Operator또는 이렇게:
=item About the C<-M> Operator섹션으로의 링크는 이렇게 생겨요:
L<somedoc/About the C<-M> Operator>포매터는 링크를 해결할 목적으로 마크업을 무시하고 섹션 이름의 렌더링 가능한 문자만 사용하기로 선택할 수 있어요. 이렇게:
<h1><a name="About_the_-M_Operator">About the <code>-M</code> Operator</h1> ... <a href="somedoc#About_the_-M_Operator">About the <code>-M</code> Operator" in somedoc</a> -
이전 perlpod 버전은
L<name/"section">링크와L<name/item>링크(그리고 그 대상)를 구별했어요. 이들은 현재 명세에서 문법적으로·의미적으로 병합되었고, section 은 "=head n Heading Content" 명령이나 "=item Item Content" 명령 어느 쪽을 가리킬 수 있어요. 이 명세는 주어진 문서에 여러 것이 모두 같은 section 식별자를 만드는 것처럼 보일 때(... 요소에서 여러 것이 모두 같은 anchorname 을 만드는 HTML처럼) 어떤 행동이어야 하는지 규정하지 않아요. POD 프로세서가 이 행동을 통제할 수 있다면 첫 번째 그런 앵커를 써야 해요. 즉L<Foo/Bar>는 Foo의 첫 "Bar" 섹션을 가리켜요.하지만 일부 프로세서/형식에서는 이를 쉽게 통제할 수 없어요. HTML 예시처럼, 여러 모호한 ...의 행동은 브라우저가 결정하도록 남겨두는 게 가장 쉽죠.
-
L<text|...>코드에서 text는 포매팅이나 E<...> 이스케이프용 서식 코드를 포함할 수 있어요. 이렇게:L<B<ummE<234>stuff>|...>"name|" 부분이 없는
L<...>코드에는E<...>와Z<>코드만 발생할 수 있어요. 즉 저자는 "L<B<Foo::Bar>>"를 사용해선 안 돼요.하지만 서식 코드와 Z<>가 L<...>의 어느 부분(name, section, text, url)에도 발생할 수 있다는 점을 주의하세요.
저자는 L<...> 코드를 중첩해서는 안 돼요. 예를 들어 "L<The LFoo::Bar man page>"는 오류로 취급해야 해요.
-
POD 저자는 "L<text|name>"의 "text" 부분 안에 서식 코드를 쓸 수 있다는 점을 주의하세요. (L<text|/"sec"> 등도 마찬가지로요.)
즉 이것은 유효해요:
Go read L<the docs on C<$.>|perlvar/"$.">L<...> 코드를 하이퍼텍스트로 렌더링하는 것을 허용하는 일부 출력 형식은 링크 텍스트의 포매팅을 허용하지 않을 수 있고, 그 경우 포매터는 그 포매팅을 그냥 무시해야 할 거예요.
-
(이 글을 쓰는 시점에)
L<name>값은 두 유형이에요.L<Foo::Bar>같은 POD 페이지 이름(실제 Perl 모듈이나 @INC/PATH 디렉토리의 프로그램, 또는 그곳의 .pod 파일일 수 있어요)이거나,L<crontab(5)>같은 Unix 맨페이지 이름이에요. 이론적으로L<chmod>는 "chmod"라는 POD 페이지와 (어떤 man 섹션의) Unix 맨페이지 "chmod" 사이에서 모호해요. 하지만 "crontab(5)"에서처럼 괄호 안 문자열의 존재는 논의 중인 것이 POD 페이지가 아니라 아마 Unix 맨페이지라는 신호로 충분해요. 이 구별은 많은 POD 프로세서에 중요하지 않지만, 하이퍼텍스트 형식으로 렌더링하는 일부 프로세서는 주어진L<foo>코드를 어떻게 렌더링할지 알기 위해 구별할 필요가 있을 수 있어요. -
이전 perlpod 버전은
L<section>문법(예:L<Object Attributes>)을 허용했는데, 이건L<name>문법과 쉽게 구별되지 않았고,L<"section">은 약간 덜 모호할 뿐이었어요. 이 문법은 더 이상 명세에 없고,L</section>문법(슬래시가 이전에는 선택적이었음)으로 대체되었어요. POD 파서는L<"section">문법을, 적어도 당분간은, 참아야 해요.L<section>을L<name>과 구별하는 제안된 휴리스틱은, 공백을 포함하면 섹션 이라는 거예요. POD 프로세서는 이것이 폐기된 문법이라고 경고해야 해요.
=over...=back 영역에 대하여 (About =over...=back Regions)
"=over"..."=back" 영역은 다양한 종류의 목록 유사 구조에 쓰여요. (여기서 "영역(region)"이라는 용어는 "=over"에서 일치하는 "=back"까지의 모든 것을 아우르는 집합 용어로 써요.)
-
"=over indentlevel " ... "=back"의 0이 아닌 숫자 indentlevel 은 포매터에게 몇 "공백"(em, 또는 대략 동등한 단위)만큼 탭해야 하는지 단서를 주는 데 쓰여요. 다만 많은 포매터는 이걸 문서 기본 글꼴의 공백(또는 M) 크기와 정확히 안 맞을 수 있는 절대 측정값으로 변환해야 할 거예요. 다른 포매터는 숫자를 완전히 무시해야 할 수도 있어요. 명시적 indentlevel 파라미터의 부재는 indentlevel 값 4와 동등해요. POD 프로세서는 indentlevel 이 존재하지만
m/\A(\d*\.)?\d+\z/와 일치하는 양수가 아니면 불평할 수 있어요. -
POD 포매터의 저자들은 "=over" ... "=back"이 여러분 출력 형식의 여러 서로 다른 구조로 매핑될 수 있음을 상기해요. 예를 들어 POD를 (X)HTML로 변환할 때
- ...
- ...
- ...
...
중 어느 것으로도 매핑될 수 있어요. 마찬가지로 "=item"은 - 나
- 로 매핑될 수 있어요.
-
각 "=over" ... "=back" 영역은 다음 중 하나여야 해요:
-
"=item *" 명령만 포함하는 "=over" ... "=back" 영역. 각 명령 뒤에 어느 정도의 일반/verbatim 문단, 다른 중첩 "=over" ... "=back" 영역, "=for..." 문단, "=begin"..."=end" 영역이 따라와요. (POD 프로세서는 맨 "=item"을 마치 "=item "인 것처럼 참아야 해요.) ""가 문자 그대로의 별표, "o", 또는 어떤 진짜 불릿 문자로 렌더링될지는 POD 포매터에 맡기고, 중첩 수준에 따라 달라질 수 있어요.
-
m/\A=item\s+\d+\.?\s*\z/문단만 포함하는 "=over" ... "=back" 영역. 각 문단(또는 각 그룹) 뒤에 어느 정도의 일반/verbatim 문단, 다른 중첩 "=over" ... "=back" 영역, "=for..." 문단, 그리고/또는 "=begin"..."=end" 코드가 따라와요. 숫자는 각 섹션에서 1부터 시작해야 하고, 순서대로 그리고 숫자를 건너뛰지 않고 진행해야 한다는 점을 주의하세요. (POD 프로세서는 "=item 1" 같은 줄을 마침표가 있는 "=item 1."인 것처럼 참아야 해요.) -
"=item [text]" 명령만 포함하는 "=over" ... "=back" 영역. 각 명령(또는 각 그룹) 뒤에 어느 정도의 일반/verbatim 문단, 다른 중첩 "=over" ... "=back" 영역, "=for..." 문단, "=begin"..."=end" 영역이 따라와요. "=item [text]" 문단은
m/\A=item\s+\d+\.?\s*\z/나m/\A=item\s+\*\s*\z/와 일치해서도, 그냥m/\A=item\s*\z/와 일치해서도 안 돼요. -
"=item" 문단을 전혀 포함하지 않고, 어느 정도의 일반/verbatim 문단만, 그리고 어쩌면 중첩 "=over" ... "=back" 영역, "=for..." 문단, "=begin"..."=end" 영역도 포함하는 "=over" ... "=back" 영역. POD의 그런 item 없는 "=over" ... "=back" 영역은 HTML의 "
...
" 요소와 의미가 동등해요.
위 모든 경우에, "=over" 명령 다음의 첫 (비-"=cut", 비-"=pod") POD 문단을 검사해 어떤 유형의 "=over" ... "=back"인지 결정할 수 있다는 점에 주의하세요.
-
-
POD 포매터는 "=item text... " 문단에 임의로 큰 텍스트 양을 반드시 참아야 해요. 실제로 대부분 그런 문단은 이렇게 짧아요:
=item For cutting off our trade with all parts of the world하지만 임의로 길 수 있어요:
=item For transporting us beyond seas to be tried for pretended offenses =item He is at this time transporting large armies of foreign mercenaries to complete the works of death, desolation and tyranny, already begun with circumstances of cruelty and perfidy scarcely paralleled in the most barbarous ages, and totally unworthy the head of a civilized nation. -
POD 프로세서는 동반 문단이 없는 "=item *" / "=item number " 명령을 참아야 해요. 중간 항목이 예시예요:
=over =item 1 Pick up dry cleaning. =item 2 =item 3 Stop by the store. Get Abba Zabas, Stoli, and cheap lawn chairs. =back -
어떤 "=over" ... "=back" 영역도 제목(heading)을 포함할 수 없어요. 프로세서는 그런 제목을 오류로 취급할 수 있어요.
-
"=over" ... "=back" 영역은 내용이 있어야 한다는 점을 주의하세요. 즉 저자는 이렇게 빈 영역을 가지면 안 돼요:
=over =back그런 내용 없는 "=over" ... "=back" 영역을 보는 POD 프로세서는 무시하거나 오류로 보고할 수 있어요.
-
프로세서는 문서 끝까지 가는 "=over" 목록(즉 일치하는 "=back"이 없는)을 참아야 하지만, 그런 목록에 대해 경고할 수 있어요.
-
POD 포매터의 저자는 이 구조가 의미상 모호하다는 점을 주의해야 해요. 어떤 식으로든 포맷팅 결정을 약간 어렵게 만들죠:
=item Neque =item Porro =item Quisquam Est Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. =item Ut Enim한편으로는 항목 "Neque", 또 다른 항목 "Porro", 또 다른 항목 "Quisquam Est"의 언급으로, 마지막 것만 설명 문단 "Qui dolorem ipsum quia dolor..."을 요구하는 것일 수 있어요. 그리고 항목 "Ut Enim"도요. 그 경우 이렇게 포맷팅하고 싶을 거예요:
Neque Porro Quisquam Est Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut Enim하지만 똑같이 세 (관련되거나 동등한) 항목 "Neque", "Porro", "Quisquam Est"에 대한 논의로, 모두를 설명하는 문단이 뒤따르고, 그다음 새 항목 "Ut Enim"이 오는 것일 수도 있어요. 그 경우 아마 이렇게 포맷팅하고 싶을 거예요:
Neque Porro Quisquam Est Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut Enim하지만 (예측 가능한 미래에는) POD는 저자가 위 "=item"-클러스터 구조로 어떤 그룹핑이 의도됐는지 구별할 방법을 제공하지 않아요. 그래서 포매터는 이렇게 포맷팅해야 해요:
Neque Porro Quisquam Est Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut Enim즉 항목들 사이와 문단들 사이에 (최소한 대략) 동등한 간격이 있어야 해요. (비록 그 간격이 텍스트 줄의 전체 높이보다 작을 수 있지만요.) 이는 독자가 (문)맥락 단서를 써서 "Qui dolorem ipsum..." 문단이 "Quisquam Est" 항목에만 적용되는지, 아니면 세 항목 "Neque", "Porro", "Quisquam Est" 모두에 적용되는지 알아내게 남겨둬요. 이상적이진 않지만, 저자의 의도에 실제로 어긋날 수 있는 포맷팅 단서를 제공하는 것보단 낫죠.
데이터 문단과 "=begin/=end" 영역에 대하여 (About Data Paragraphs and "=begin/=end" Regions)
데이터 문단은 보통 문서를 특정 형식으로 렌더링할 때 사용될(보통 통과될) 비-POD 데이터를 인라인하는 데 쓰여요:
=begin rtf
\par{\pard\qr\sa4500{\i Printed\~\chdate\~\chtime}\par}
=end rtf
정확히 같은 효과는, 부수적으로, 단일 "=for" 문단으로도 달성할 수 있어요:
=for rtf \par{\pard\qr\sa4500{\i Printed\~\chdate\~\chtime}\par}
(공식적으로 데이터 문단은 아니지만, 하나와 같은 의미를 갖고 POD 파서는 그것을 데이터 문단으로 파싱할 수 있어요.)
데이터 문단의 또 다른 예:
=begin html
I like <em>PIE</em>!
<hr>Especially pecan pie!
=end html
이들이 일반 문단이었다면 POD 파서는 (첫 문단의) "E"을 "E
추가 예로: (이 글을 쓰는 시점에) "biblio" 식별자는 지원되지 않지만, 어떤 프로세서가 그것을 (말하자면) 서지 참조를 나타내는(단순 문단에 서식 코드를 필연적으로 포함하는) 방법으로 인식하도록 쓰였다고 가정해볼게요. "biblio" 문단이 일반 처리를 위한 것임은 각 "biblio" 식별자 앞에 콜론을 붙여 표시해요:
=begin :biblio
Wirth, Niklaus. 1976. I<Algorithms + Data Structures =
Programs.> Prentice-Hall, Englewood Cliffs, NJ.
=end :biblio
이것은 파서에게 이 begin...end 영역의 문단이 일반·verbatim 문단으로서의 정상 처리를 받는다는 신호가 돼요 ("biblio" 식별자를 이해하는 프로세서만을 위한 것이라는 태그가 여전히 붙으면서). 같은 효과는 이렇게도 얻을 수 있어요:
=for :biblio
Wirth, Niklaus. 1976. I<Algorithms + Data Structures =
Programs.> Prentice-Hall, Englewood Cliffs, NJ.
이 식별자의 ":"은 단순히 "결과가 어떤 특수 대상용일지라도, 이걸 정상적으로 처리해라"를 뜻해요. 파서 API가 "biblio"를 대상 식별자로 보고하면서 ":" 접두사가 있었음을 보고하길 제안해요. (마찬가지로 위 "html"에서 "html"을 대상 식별자로 보고하고 ":" 접두사의 부재 를 주목하세요.)
identifier 가 콜론으로 시작하는 "=begin identifier "..."=end identifier " 영역은 명령을 포함할 수 있다는 점을 주의하세요. 예를 들어:
=begin :biblio
Wirth's classic is available in several editions, including:
=for comment
hm, check abebooks.com for how much used copies cost.
=over
=item
Wirth, Niklaus. 1975. I<Algorithmen und Datenstrukturen.>
Teubner, Stuttgart. [Yes, it's in German.]
=item
Wirth, Niklaus. 1976. I<Algorithms + Data Structures =
Programs.> Prentice-Hall, Englewood Cliffs, NJ.
=back
=end :biblio
하지만 identifier 가 콜론으로 시작하지 않는 "=begin identifier "..."=end identifier " 영역은 "=head1" ... "=head4" 명령이나 "=over", "=back", "=item"을 직접 포함해서는 안 된다는 점을 주의하세요. 예를 들어 이건 유효하지 않은 것으로 간주될 수 있어요:
=begin somedata
This is a data paragraph.
=head1 Don't do this!
This is a data paragraph too.
=end somedata
POD 프로세서는 위(특히 "=head1" 문단)가 오류라고 신호할 수 있어요. 하지만 다음은 오류로 취급하면 안 된다는 점을 주의하세요:
=begin somedata
This is a data paragraph.
=cut
# Yup, this isn't Pod anymore.
sub excl { (rand() > .5) ? "hoo!" : "hah!" }
=pod
This is a data paragraph too.
=end somedata
그리고 이것도 유효해요:
=begin someformat
This is a data paragraph.
And this is a data paragraph.
=begin someotherformat
This is a data paragraph too.
And this is a data paragraph too.
=begin :yetanotherformat
=head2 This is a command paragraph!
This is an ordinary paragraph!
And this is a verbatim paragraph!
=end :yetanotherformat
=end someotherformat
Another data paragraph!
=end someformat
위 "=begin :yetanotherformat" ... "=end :yetanotherformat" 영역의 내용 은 데이터 문단이 아니에요. 즉시 포함하는 영역의 식별자(":yetanotherformat")가 콜론으로 시작하기 때문이에요. 실제로 데이터 문단을 포함하는 대부분의 영역은 데이터 문단만 포함할 거예요. 하지만 위 중첩은 드물더라도 POD로서 문법적으로 유효해요. 하지만 "html" 같은 일부 형식의 핸들러는 중첩 영역이 아니라 데이터 문단만 받아들일 거예요. 그리고 (자신을 대상으로 한) 중첩 영역이나 "=end", "=pod", "=cut" 외의 명령을 보면 불평할 수 있어요.
이 유효한 구조도 고려해볼게요:
=begin :biblio
Wirth's classic is available in several editions, including:
=over
=item
Wirth, Niklaus. 1975. I<Algorithmen und Datenstrukturen.>
Teubner, Stuttgart. [Yes, it's in German.]
=item
Wirth, Niklaus. 1976. I<Algorithms + Data Structures =
Programs.> Prentice-Hall, Englewood Cliffs, NJ.
=back
Buy buy buy!
=begin html
<img src='wirth_spokesmodeling_book.png'>
<hr>
=end html
Now now now!
=end :biblio
여기서 "=begin html"..."=end html" 영역은 더 큰 "=begin :biblio"..."=end :biblio" 영역 안에 중첩돼 있어요. "=begin html"..."=end html" 영역의 내용은 데이터 문단인데, 즉시 포함하는 영역의 식별자("html")가 콜론으로 시작하지 않기 때문이에요.
POD 파서는 (단일 영역 안에서) 일련의 데이터 문단을 연달아 처리할 때, 그것들이 빈 줄을 포함하는 하나의 큰 데이터 문단이라고 간주해야 해요. 그래서 위 "=begin html"..."=end html"의 내용 은 두 데이터 문단으로 저장될 수 있지만("
\n" 하나와 "
\n" 하나), 단일 데이터 문단("
\n\n\n")으로 저장되어야 해요.
POD 프로세서는 빈 "=begin something "..."=end something " 영역, 빈 "=begin :something "..."=end :something " 영역, 내용 없는 "=for something "과 "=for :something " 문단을 참아야 해요. 즉 이들을 참아야 해요:
=for html
=begin html
=end html
=begin :biblio
=end :biblio
부수적으로, 명령처럼 보이는 것으로 시작하는 데이터 문단을 표현하는 쉬운 방법이 없다는 점을 주의하세요. 고려해볼게요:
=begin stuff
=shazbot
=end stuff
여기서 "=shazbot"은 데이터 문단 "=shazbot\n"이 아니라 POD 명령 "shazbot"으로 파싱될 거예요. 하지만 "=shazbot\n"으로 이뤄진 데이터 문단은 이 코드로 표현할 수 있어요:
=for stuff =shazbot
이게 필요한 상황은 아마 아주 드물 거예요.
=end 명령은 현재 열려 있는 =begin 명령과 일치해야 한다는 점을 주의하세요. 즉 적절히 중첩되어야 해요. 예를 들어 이것은 유효해요:
=begin outer
X
=begin inner
Y
=end inner
Z
=end outer
반면 이것은 유효하지 않아요:
=begin outer
X
=begin inner
Y
=end outer
Z
=end inner
후자가 부적절한 이유는 "=end outer" 명령이 보일 때 현재 열려 있는 영역의 formatname이 "outer"가 아니라 "inner"이기 때문이에요. ("outer"가 더 높은 영역의 형식 이름이라는 건 우연일 뿐이에요.) 이건 오류예요. 프로세서는 기본적으로 이걸 오류로 보고해야 하고, 그 오류를 포함하는 문서 처리를 중단할 수 있어요. 이의 귀결은 영역이 "겹칠" 수 없다는 거예요. 즉 위 후자 블록은 X와 Y를 포함하는 "outer" 영역이 Y와 Z를 포함하는 "inner" 영역과 겹치는 것을 나타내지 않아요. 유효하지 않기 때문에(모든 겉보기 겹치는 영역이 그렇듯) 그것도 아무것도 나타내지 않아요.
마찬가지로 이것도 유효하지 않아요:
=begin thing
=end hting
영역이 "thing"으로 열렸고 "=end"가 "hting" [sic]을 닫으려 하므로 이건 오류예요.
이것도 유효하지 않아요:
=begin thing
=end
모든 "=end" 명령은 formatname 파라미터가 있어야 하므로 이건 유효하지 않아요.
함께 보기 (SEE ALSO)
perlpod, perlsyn의 "PODs: Embedded Documentation", podchecker
저자 (AUTHOR)
Sean M. Burke
Perldoc Browser는 Dan Book(DBOOK)이 유지보수해요. 사이트 자체, 검색, 문서 렌더링 관련 문제는 GitHub issue tracker로 연락하세요.
Perl 문서는 Perl 5 Porters가 Perl 개발 과정에서 유지보수해요. 문서 내용이나 형식 관련 문제는 Perl issue tracker, 메일링 리스트, 또는 IRC로 연락하세요.