perlpodspec - Plain Old Documentation: フォーマット仕様とメモ
この文書は、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 するべきです(should)」と 表現されます。 これはパーサが(そのままの段落でタブを展開するといった)機能 Y を オフにするかどうかのオプションを提供することを要求している わけではありませんが、 このようなオプションが提供されている かもしれない ことを示しています。
Pod は他のファイル (典型的には Perl ソースファイル) に埋め込まれていますが、 Pod 以外のことは全く知らなくても Pod を書けます。
ファイルの 行 (line) は 0 個以上の改行でない文字で構成され、 改行かファイルの終わりで終端されます。
改行シーケンス (newline sequence) は普通プラットフォーム依存の 概念ですが、Pod パーサは CR (ASCII 13), LF (ASCII 10), CRLF (ASCII 13 の直後に ASCII 10) に加えて、その他の システム固有の意味ののどれでも認識するべきです(should)。 ファイルの最初の CR/CRLF/LF シーケンスを、ファイルの残りをパースするための 改行を識別するための基準として使ってもかまいません(may)。
空行 (blank line) は 0 個以上のスペース (ASCII 32) かタブ (ASCII 9) のみで 構成され、改行かファイルの終わりで終端されます。 非空行 (non-blank line) はスペースとタブ以外の文字 1 個以上を含みます (そして改行かファイルの終わりで終端されます)。
(注意: 古い Pod パーサの多くはスペースとタブで構成される行を 受け付けず、改行を空行として扱います。 これらのパーサは 何の文字も含まれていない 行だけを空行として 扱います。)
空白 (whitespace) は、この文書ではスペース、タブ、改行シーケンスを 総称する用語です。 (それ自体、この用語は普通リテラルな空白を参照します。 これは、Pod ソース中の空白文字の並びです; 一方 "E<32>" は 空白文字を 意味する フォーマッティングコードです。)
Pod パーサ (Pod parser) は Pod をパースするためのモジュールです (これはコールバックを呼び出すかパース木を構築するか直接フォーマットするかに 関わりません)。 Pod フォーマッタ (Pod formatter) (または Pod トランスレータ (Pod translator)) は Pod を他の形式 (HTML, プレーンテキスト、Tex, PostScript, RTF) に変換するモジュールかプログラムです。 Pod プロセッサ (Pod processor) はフォーマッタあるいはトランスレータか、 あるいは Pod に何かの処理(単語を数える、インデックスをスキャンする、など)を 行うプログラムかも知れません。
Pod の内容は Pod ブロック (Pod blocks) に含まれています。 一つの Pod ブロックは m/\A=[a-zA-Z]/
にマッチングする行で開始し、 m/\A=cut/
にマッチングする次の行までか、もし m/\A=cut/
行がなければファイルの最後まで続きます。
パーサーは、ヒヤドキュメントのように、pod のように見えるけれども クォート文字列の中にあるのを区別することを装丁していないことに 注意してください。
Pod ブロックの内部は、Pod 段落(Pod paragraphs) です。 一つの Pod 段落は、1 以上の空行で分割された非空行のテキストで構成されます。
Pod 処理のために、Pod ブロックには 4 種類の段落があります:
コマンド段落 (command paragraph) (「指示子」(directive) とも呼ばれます)。 段落の最初の行は m/\A=[a-zA-Z]/
にマッチングしなければなりません(must)。 コマンド段落は典型的には以下のように 1 行です:
=head1 NOTES
=item *
しかし複数の (非空行の) 行にわたってもかまいません(may):
=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 paragraph)。 この段落の最初の行はリテラルのスペースかタブでなければならず(must)、 この段落は "identifier" がコロン (":") で始まっていない限り "=begin identifier", ... "=end identifier" を内部に 含んではいけません(must not)。 つまり、もし段落がリテラルのスペースかタブで始まっているけれども、 内部に "=begin identifier", ... "=end identifier" 領域がある場合、 "identifier" がコロンで始まっていない限りデータ段落です。
空白はそのままの段落では 意味を持ちます (しかし、処理中に、タブは おそらく展開されます)。
通常の段落 (ordinary paragraph)。 最初の行が m/\A=[a-zA-Z]/
にも m/\A[ \t]/
にもマッチングせず、 かつ、コロン (":") 以外で始まる "identifier" に対する "=begin identifier" ... "=end identifier" シーケンスの内側で ない段落は、通常の段落です。
データ段落 (data paragraph)。 これは "=begin identifier" ... "=end identifier" シーケンスの 内部で、"identifier" がリテラルのコロン (":") で 始まって いない ものです。 ある意味では、データ段落は Pod の一部ではありません (事実上「帯域外」です); なぜならほとんどの種類の 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" 領域がない)のでそのままの段落です。
"=begin identifier" ... "=end identifier" コマンドは、 identifier がコロンで始まっていないなら、その内部の段落を、 通常の段落やそのままの段落として解釈するのを停止させます。 これは "About Data Paragraphs and "=begin/=end" Regions" の節で詳しく 議論しています。
この章は "Command Paragraph" in perlpod での議論を補完して明確化することを 目的にしています。 現在認識されている Pod コマンドは以下の通りです:
このコマンドは、この段落の残りの文章が見出しであることを示します。 この文章にはフォーマッティングコードを含むことができます。 例:
=head1 Object Attributes
=head3 What B<Not> to Do!
このコマンドは、この段落から Pod ブロックが始まることを示します。 (すでに Pod ブロックの内部である場合は、このコマンドは何の効果も ありません。) もしこのコマンド段落の "=pod" の後に何らかの文章がある場合、 無視しなければなりません(must)。 例:
=pod
This is a plain Pod paragraph.
=pod This text is ignored.
このコマンドは、この行が Pod ブロックの終わりであることを示します。 この行の "=cut" の後にテキストがあれば、これは 無視しなければなりません(must)。 例:
=cut
=cut The documentation ends here.
=cut
# This is the first line of program text.
sub foo { # This is the second.
Pod ブロックを "=cut" コマンドで 開始 しようとするとエラーになります。 この場合、Pod プロセッサは入力ファイルのパースを中止しなければならず(must)、 デフォルトでは警告を出力しなければなりません(must)。
このコマンドは、これがリスト/インデント領域の開始であることを示します。 "=over" に引き続いてなんらかのテキストがある場合は、それは非ゼロの 正数のみでなければなりません(must)。 この数値の意味論はかなり後ろの "About =over...=back Regions" の節に あります。 フォーマッティングコードは展開されません。 例:
=over 3
=over 3.5
=over
このコマンドは、ここからリストの中のアイテムが始まることを示します。 フォーマッティングコードは処理されます。 この段落の(オプションである)残りのテキストの意味論はかなり後ろの "About =over...=back Regions" の節にあります。 例:
=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.
このコマンドは、ここがもっとも近い位置の "=over" コマンドで始まった領域の 終わりであることを示します。 "=back" コマンドの後にテキストを置くことは許されません。
これは、引き続く段落 (マッチングする "=end formatname" まで) が なんらかの特殊な処理をするためのものであることを示します。 "formatname" がコロンで始まっていなければ、含まれている非コマンド段落は データ段落です。 しかし、もし "formatname" がコロンで 始まっている なら、非コマンド段落は 通常の段落かデータ段落です。 これは "About Data Paragraphs and "=begin/=end" Regions" の節で詳しく 議論しています。
formatname は正規表現 m/\A:?[-a-zA-Z0-9_]+\z/
にマッチングすることを 勧めます。 formatname の後ろの空白に引き続く全てのものは、フォーマッタがこの 領域を扱うときに使われるかも知れないパラメータです。 このパラメータは "=end" 段落では繰り返されてはいけません(must not)。 実装者は "=begin"/"=end"/"=for" の最初の引数の意味論と文法の将来の拡張に 備えるべきです(should)。
これはマッチングする "=begin formatname" 領域によって開かれた領域の 終わりを示します。 "formatname" が直近に開かれた "=begin formatname" 領域の formatname では ない場合、これはエラーであり、エラーメッセージを 生成しなければなりません(must)。 これは "About Data Paragraphs and "=begin/=end" Regions" の節で詳しく 議論しています。
これは以下と同等です:
=begin formatname
text...
=end formatname
つまり、これは単一の段落からなる領域を作成します; この段落は、 "formatname" が ":" で始まっているなら通常の段落として扱われます; "formatname" がコロンで 始まっていない なら、"text..." は データ段落を構成します。 "text..." をそのままの段落として記述するために "=for formatname text..." を 使う方法はありません。
このコマンドは(文書の最初の方に(少なくとも非 US-ASCII データが出てくる 前に!)書くべきです(should))、この文書がエンコーディング encodingname で エンコードされていることを宣言します; これは Encode が認識する エンコーディングでなければなりません(must)。 (Encode::Supported にある、Encode が対応するエンコーディングの一覧が 便利です。) Pod パーサが宣言されたエンコーディングでデコードできない場合は、 警告を出力するべき(should)で、文書のパースを中断してもかまいません(may)。
複数の "=encoding" 行を持つ文書はエラーとして扱われるべきです(should)。 Pod プロセッサは、最初以外の "=encoding" 行が最初のものと同じ場合 (例えば、"=encoding utf8" 行があって、その後また "=encoding utf8" 行が あった場合)は黙って許容してもかまいません(may)。 しかし Pod プロセッサは、同じ文書に矛盾する "=encoding" 行がある場合 (例えば、文書の最初の方に "=encoding utf8" があって、その後 "=encoding big5" 行があった場合) エラーにするべきです(should)。 BOM を認識する Pod プロセッサは、BOM と矛盾する "=encoding" 行がある場合 (例えば、文書が UTF-16LE BOM で始まっていて "=encoding shiftjis" 行がある 場合)、エラーにしてもかまいません(may)。
Pod プロセッサが上に示した以外のコマンド ("=head", "=haed1", "=stuff", "=cuttlefish", "=w123" など)に遭遇した場合、プロセッサはデフォルトでは エラーとして扱わなければなりません(must)。 このようなコマンドで始まる段落を処理してはならず(must not)、デフォルトでは エラーとして警告しなければならず(must)、パースを 中断してもかまいません(may)。 Pod パーサは、特定のアプリケーションのために、上述の既知のコマンドの一覧に 追加して、それぞれの追加コマンドに対して、フォーマッティングコードを 処理するかどうかを規定する方法を認めてもかまいません(may)。
この仕様の将来のバージョンでは追加のコマンドが追加されるかもしれません。
(この文書の以前の草案と以前の 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]) で始まり、2 個以上の "<"、 1 個以上の空白文字、任意の数の文字、1 個以上の空白文字が続き、 このフォーマッティングコードの最初にあった "<" と同じ数の ">" で 終わるフォーマッティングコード。 例:
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::Parsar の parse_text
ルーチンの コードを参考にするべきです。
I<text>
-- イタリック文字"Formatting Codes" in perlpod にある簡潔な議論を参照してください。
B<text>
-- ボールド文字"Formatting Codes" in perlpod にある簡潔な議論を参照してください。
C<code>
-- コード文字"Formatting Codes" in perlpod にある簡潔な議論を参照してください。
F<filename>
-- ファイル名用のスタイル"Formatting Codes" in perlpod にある簡潔な議論を参照してください。
X<topic name>
-- インデックスエントリ"Formatting Codes" in perlpod にある簡潔な議論を参照してください。
このコードは特殊で、ほとんどのフォーマッタはこのコードとその内容は 完全に捨てられます。 その他のフォーマッタは現在の文書のインデックス構築に使える 見えないコードとしてレンダリングされます。
Z<>
-- a null (zero-effect) formatting code"Formatting Codes" in perlpod で簡潔に議論されています。
このコードは特殊で、内容はなしであるべきです(should)。 つまり、プロセッサが Z<potatoes>
を見ると異常とみなしても かまいません(may)。 異常とみなすかどうかに関わらず、potatoes という文字は 無視されるべきです(should)。
L<name>
-- ハイパーリンクこのコードの複雑な文法は "Formatting Codes" in perlpod で詳細に 議論されていて、実装の詳細は後述する "About L<...> Codes" に あります。 L<content> の内容のパースはトリッキーです。 特に、E<...> コードが解決される 前に 、 内容が URL のように見えるか、あるいは内容が "|" や "/" で 分割する必要があるか (右順序で!) などです。
E<escape>
-- 文字エスケープ"Formatting Codes" in perlpod と、 "Notes on Implementing Pod Processors" にあるいくつかのポイントを 参照してください。
S<text>
-- ノーブレークスペースを含む文字列このフォーマッティングコードは文法的には単純ですが、意味論的には複雑です。 これが意味することは、このコードの内容にあるそれぞれのスペースは ノーブレークスペースとして認識されるということです。
以下のものを考えます:
C<$x ? $y : $z>
S<C<$x ? $y : $z>>
どちらも "$x"、一つのスペース、"?"、一つのスペース、":"、一つのスペース、 "$z" からなる、固定幅 (コードスタイル) 文字列として認識されます。 違いは、S コードの付いている後者は、これらのスペースは「普通の」 スペースではなく、ノーブレークスペースであるということです。
Pod プロセッサが ("N<...>" や "Q<...>" のような) 上述のもの 以外のフォーマットコードに出会った場合、プロセッサはデフォルトでは エラーとして扱わなければなりません (must)。 Pod パーサは、特定のアプリケーションのために、上述の既知のフォーマッティング コードの一覧に追加する方法を認めてもかまいません(may); Pod パーサは追加されたコマンドそれぞれに対して、L<...> が しているように、特殊処理のためのある種の形式を要求するかどうかを 規定しているかもしれません。
この仕様の将来のバージョンでは追加のフォーマッティングコードが 追加されるかもしれません。
ヒストリカルノート: いくつかの古い Pod プロセッサは、"-" の直後にある ">" を、閉じ "C<" コードとして扱いません。 これにより、以下のようなものが:
C<$foo->bar>
以下のものと等価として扱われ:
C<$foo-E<gt>bar>
"$foo-" だけが含まれる "C" フォーマッティングコードの後 "C" フォーマッティングコード の外にある "bar>"、と等価にはなりません。 この問題は以下のような文法の追加によって解決されました:
C<< $foo->bar >>
準拠しているパーサは "->" を特別扱いしてはいけません (must not)。
フォーマッティングコードは絶対に段落をまたげません。 もしコードがある段落で開き、その段落の終わりまでに閉じコードがない場合、 Pod パーサはフォーマッティングを閉じなければならず(must)、 また ("Unterminated I code in the paragraph starting at line 123: 'Time objects are not...'" のような) エラーを出力するべきです (should)。 従って、これら二つの段落は:
I<I told you not to do this!
Don't make me say it again!>
(I コードが一つ目の段落から始まって次の段落でも始まっているという形で) 二つの段落をイタリックとしてパース してはいけません(must not)。 代わりに、最初の段落は警告を生成するべきです(should)ですが、それを 置いておいて、上述のコードは以下のようであるかのように パースしなければなりません(must):
I<I told you not to do this!>
Don't make me say it again!E<gt>
(SGML 的な jargon で言うなら、全ての Pod コマンドはブロックレベル要素の ようなもので、一方全ての Pod フォーマッティングコードはインライン要素の ようなものです。)
以下は、Pod の処理を行うためのさまざまな要求と提案の長いリストです。
Pod フォーマッタは、たとえテキストがページからはみ出すのを避けるために (とても長い行に対しては複数回)分割しないといけないとしても、 任意の長さのそのままのブロックの行を許容するべきです(should)。 Pod フォーマッタはそのような行分割に対して警告を出してもかまいません(may)。 この警告は特に、(普通は意図したものではない) 100 文字以上の行に対して 出すのが適切です。
Pod パーサは 3 種類のよく知られた改行 (CR, LF, CRLF) の 全て を 認識しなければなりません(must)。 perlport を参照してください。
Pod パーサは任意の長さの入力行を受け付けるべきです(should)。
Perl は、ファイルの先頭に付けることでファイルが UTF-16 (ビッグエンディアンかリトルエンディアンか)あるいは UTF-8 かを 示すためにファイルの先頭に付けるバイト順マーク(Byte Order Mark)を 認識するので、Pod パーサも同様であるべきです(should)。 さもなければ、ファイル中の最初の最上位ビットの立ったバイトシーケンスが UTF-8 シーケンスとして有効であるように見える場合は文字エンコーディング UTF-8 と、そうでなければ CP-1252 と認識するべきです(should) (この仕様の以前の版では CP-1252 ではなく Latin-1 を使っていました)。
この仕様の将来のバージョンでは Pod がその他のエンコーディングをどのように 受け入れるかが指定されるかもしれません。 おそらく Pod パース中のその他のエンコーディングの扱いは XML のパースと 同じようになるでしょう: 特定の Pod ファイルでどのエンコーディングが 宣言されたとしても、内容は Unicode 文字としてメモリに補完されます。
よく知られているバイト順マークには以下のものがあります: もしファイルが二つのリテラルバイト値 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);
並びが有効な UTF-8 (RFC 2279) かどうかを見るための、 BOM なしファイルの(コード内か POD内内かに関わらず)最初の最上位ビットが 立ったバイト並びをテストするという単純だけれども ASCII プラットフォームでは 十分な発見法は、並びの最初のバイトが 0xC2 - 0xFD の範囲 かつ 次のバイトの 範囲が 0x80 - 0xBF であるかどうかを調べることです。 もしそうなら、パーサはこのファイルが UTF-8 で、そのファイルの全ての 最上位ビットが立った並びが UTF-8 であると結論づけてもかまいません(may)。 さもなければパーサはそのファイルを CP-1252 として扱うべきです (should)。 (より良く、EBCDIC プラットフォームでも動作するチェックは、 並びのコピーを utf8::decode() に渡すことで、これは並びの 完全な正当性チェックを実行し、これが有効な UTF-8 なら TRUE を、さもなければ FALSE を返します。 この関数は常に事前読み込みされ、C で書かれているので高速で、 最大でも 1 回だけしか呼び出されないので、性能を考慮してこれを避ける 必要はありません。) 真に 非 UTF-8 のファイルの最初の最上位ビットが立った並びがたまたま UTF-8 に見えるというのはありそうにない状況なので、明確に UTF-8 として 有効 ではない、最上位ビットが立った並びを含むコメント行を置くことで 我々のヒューリスティック(およびさらに賢いヒューリスティック)を 満たすことができます。 単なる "#"、鋭アクセント e、最上位ビットが立っていないバイト、からなる 行は、このファイルのエンコーディングを決定するのに十分です。
Pod プロセッサは、"=for [label] [content...]" 段落を、 "=begin [label]" 段落、内容、"=end [label]" 段落と同じように 扱わなければなりません(must)。 (パーサはこれら二つの構文を融合してもかまいません(may)し、別々のままに してもかまいません(may); フォーマッタはどちらにしても同じように扱います。)
Pod を、コメントが許されるフォーマット (つまり、ほぼ、プレーンテキスト以外の あらゆるフォーマット) にレンダリングするとき、 Pod フォーマッタは、自身の名前とバージョン番号、および Pod を 処理するときに使った全てのモジュールの名前とバージョン番号が識別できる コメントを挿入しなければなりません(must)。 最小限の例:
%% 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 のバージョンといった 追加のコメントを挿入してもかまいません(may)。
フォーマッタは、エラー/警告を、(STDERR へのメッセージや die
として) その他の場所への出力に加えて、またはそれに代えて、コメントとして 記録することを選択してもかまいません(may)。
Pod パーサは警告やエラーメッセージ ("Unknown E code E<zslig>!") を (STDERR に print するか warn
や carp
を使うか die
や croak
を 使うかに関わらず) STDERR に出力しても かまいません (may) が、 そのような全ての STDERR 出力を抑制して、代わりに、コールバックを 引き起こすことによってか、エラーを文書オブジェクトの何らかの属性または 同様の控えめな機構によって記録するか、あるいは文書のパースされた形式の 末尾に "Pod Errors" 節を追加する方法でも、何らかの他の方法でエラー/警告を 報告するためのオプションを認めなければなりません(must)。
極端に異常な文書の場合は、Pod パーサはパースを中断してもかまいません(may)。 それでも、die
/croak
の使用は避けます; 可能なら、パーサは単に 入力ファイルを閉じて、メモリにある文書(の一部)の末尾に "*** Formatting Aborted ***" のような文章を追加してもかまいません(may)。
(E<...>, B<...> のような)フォーマッティングコードを理解する 段落 (つまり、そのままの段落は 含みません が、通常の段落および "=head1" のようなレンダリングされるテキストを出力するコマンド段落を 含みます)では、リテラルな空白は一般的に「重要でない」と 考えられるべきです(should); 一つのリテラルな空白は任意の(非 0 の) 数のリテラルな空白、リテラルな改行、リテラルなタブは (これにより空行(これは段落の終わりになるので)を出力しない限り)、 同じ意味になります。 Pod パーサはそれ園れの処理された段落でのリテラルな空白を 詰めるべきです(should)が、(いくつかの処理タスクはこれを必要としないので)、 これを上書きするオプションを提供してもかまいません(may)し、 追加の特殊ルール(例えば、ピリオド-空白-空白やピリオド-改行の並びを 特別扱いするなど)に従ってもかまいません(may)。
Pod パーサはデフォルトでは、アポストロフィ (') とクォート (") を スマートクォート (小さい 9's, 66's, 99's, など)にしようとしたり、 逆クォート (`) を(開きクォート文字と区別するために!)単一の 逆クォート文字以外に変えようとしたり、"--" を二つのマイナス記号以外に 変えようとするべきではありません(should not)。 これらを C<...> 中のテキストには 決して 行っては いけません(must not)し、そのままの段落のテキストには 決して決して 行ってはいけません(must not)。
Pod を、改行なしのハイフン (-) と改行可能なハイフン ("object-oriented" のようなときに、"object-"、改行、"oriented" と 分割できるもの) の 2 種類があるフォーマットにレンダリングするときは、 フォーマッタは一般的に "-" を改行なしのハイフンに変換することが 推奨されますが、これらの一部を改行するハイフンに変換するための 発見的手法を適用してもかまいません(may)。
Pod フォーマッタは、Perl コードの単語が行をまたがないように合理的な努力を 行うべきです(should)。 例えば、一部のフォーマッティングシステムでの"Foo::Bar" は、 "Foo::" 改行 "Bar" や、"Foo::-" 改行 "Bar" のように行をまたいで 分割しても有効です。 これは、可能なところでは、単語の途中での全ての行分割を無効にするか、 特定の単語を「これは行をまたがない」コードの内部的な句読点 (一部のフォーマットでは単一のコードではなく、非分割ゼロ幅空白を単語の文字の それぞれの組の間に挿入するという形かもしれません)で包むことで 防ぐべきです(should)。
Pod パーサは、デフォルトでは、フォーマッタやその他のプロセッサに 渡す前に、そのままの段落のタブを展開するべきです(should)。 パーサはこれを上書きするオプションを許してもかまいません(may)。
Pod パーサは、デフォルトでは、通常の段落とそのままの段落の末尾の 改行を、フォーマッタに渡す前に削除するべきです(should)。 例えば、今読み込んでいる段落が Pod ソースでは空行を含んでいて、 それで終わっていると考えられる一方、 この文を終わらせるピリオド文字を含んでいて、それで終わっているかのように 処理するべきです(should)。
Pod パーサは、エラーを報告するときは、単に段落番号を報告する ("Nested E<>'s in Paragraph #52 of Thing/Foo.pm!") のではなく、 およその行番号を報告するための 努力を行うべきです ("Nested E<>'s in Paragraph #52, near line 633 of Thing/Foo.pm!")(should)。 これが難しいところでは、段落番号は少なくとも段落の抜粋と共に 報告されるべきです ("Nested E<>'s in Paragraph #52 of Thing/Foo.pm, which begins 'Read/write accessor for the C<interest rate> attribute...'")(should)。
Pod パーサは、連続したそのままの段落を処理するときには、たまたま空行を 含んでいる大きな一つのそのままの段落として扱うべきです(should)。 つまり、以下のような、空行を挟んだ 2 つの行は:
use Foo;
print Foo->VERSION
フォーマッタや他のプロセッサに渡される前に一つの段落 ("\tuse Foo;\n\n\tprint Foo->VERSION") 統合されるべきです(should)。 パーサはこれを上書きするオプションを許してもかまいません(may)。
これはイベントベースの Pod パーサを実装するには厄介すぎるかもしれない一方、 パース木を返すパーサにとっては直感的です。
Pod フォーマッタは、可能なところでは、短いそのままの段落 (例えば 12 行 以下) がページをまたぐことを避けるように勧めます。
Pod パーサは空白やタブだけからなる行を、段落を分割する「空行」として 扱わなければなりません(must)。 (一部の古いパーサは、二つの連続した改行のみを「空行」として認識し、 改行、空白、改行は空行として認識しません。 これは非準拠の振る舞いです。)
Pod フォーマッタ/プロセッサの作者は、独自の Pod パーサを書くことを 避けるためにあらゆる努力を行うべきです(should)。 既に様々なインターフェーススタイルを持ったものがいくつか CPAN にあり -- その一つである Pod::Simple か最近のバージョンの Perl に同梱されています。
Pod 文書中の文字は、リテラル、E<n> コード、(E<233> と等価な E<eacute> のように) 等価なニーモニック、のいずれで伝達しても かまいません(may)。 数値は、EBCDIC プラットフォームでも Latin1/Unicode の値です。
E<n> 数値コードを使って文字を参照するとき、 よく知られている US-ASCII で参照されている範囲 32-126 の数値 (Unicode でも同じ意味で定義されいます) は、全ての Pod フォーマッタは 充実にレンダリングしなければなりません(must)。 E<> 数値が 0-31 と 127-159 の範囲の文字は、改行 (ASCII 13, ASCII 13 ASCII 10, ASCII 10 のいずれか)またはタブ (ASCII 9) のための リテラルなバイト並びを除いて、(リテラルとしてと E<number> コードとしての どちらとしても) 使われるべきではありません (should not)。
範囲 160-255 の数値は Latin-1 文字 (Unicode でも同じ意味で 定義されています) を参照します。 255 を超える数値は Unicode 文字を参照していると理解するべきです(should)。
一部のフォーマッタは 32-126 の範囲外の文字を確実にレンダリングすることが 出来ず、多くのフォーマッタは 32-126 と 160-255 は扱えるものの、 255 を超える文字は扱えないことを警告しておきます。
小なりと大なりを表すよく知られた "E<lt>" と "E<gt>" の他に、 Pod パーサは "/" (スラッシュ) のための "E<sol>" と "|" (垂直バー、 パイプ) のための "E<verbar>" を理解しなければなりません(must)。 Pod パーサはまた、"E<lchevron>" と "E<rchevron>" を 文字 171 と 187 の古いコードとして理解するべきです(should); つまり、 "left-pointing double angle quotation mark" = "left pointing guillemet" で、"right-pointing double angle quotation mark" = "right pointing guillemet" です。 (これらは小さい "<<" や ">>" のように見え、HTML/XHTML コードの "E<laquo>" や "E<raquo>" として表現されます。)
Pod パーサは、www.W3.org
にある最新の XHTML 仕様の実体宣言で 定義されている全ての "E<html>" コードを理解するべきです(should)。 Pod パーサは少なくとも範囲 160-255 (Latin-1) の文字を定義する エンティティを理解しなければなりません(must)。 Pod パーサは、不明な "E<identifier>" コードに出会ったとき、 (少なくともデフォルトでは)単にから文字列と置き換えるべきではなく (should not)、リテラル文字 E、小なり、identifier、大なりで構成される 文字列として渡されたものとしてもかまいません(may)。 または、Pod パーサは、そのような不明な "E<identifier>" コードを、 特にそのようなコードのためのイベントを起動するか、メモリ内文書木に 特別なノード型を追加することで処理する代替オプションを 提供してもかまいません(may)。 そのような "E<identifier>" は一部のプロセッサでは特別な意味を 持たせてもかまいませんし(may)、一部のプロセッサはこれを特別なエラー報告に 加えることを選んでもかまいません(may)。
Pod パーサは XHTML コードのうち、文字 34 (ダブルクォート, ") の ための "E<quot>"、文字 38 (アンパサンド, &) のための "E<amp>"、 文字 39 (アポストロフィ、 ') のための "E<apos>" にも 対応しなければなりません(must)。
"E<whatever>" 形式の全ての場合において、whatever (html 名でも どの基数の数値でも) は英数字のみから構成されていなければなりません(must) -- つまり、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<e-acute>" を 文法的に 不正として扱って、単に "E<qacute>" (原文のまま) のような不明な(しかし 理論的には有効な)html として生成されるエラーメッセージ(または警告や イベント) とは異なるエラーメッセージを出力するかもしれません(may)。 しかし、Pod パーサはこの区別をすることを要求はされません。
E<number> は単に「現在の/ネイティブな文字集合における符号位置 number」と 扱ってはいけない (must not) ことに注意してください。 これは常に「Unicode で符号位置 number として表現される文字」という 意味しかありません。 (これは XML での &#number; の意味論と同じです。)
これにより、おそらく多くのフォーマッタは Unicode 符号位置 (e-acute 文字のための "\xE9") からターゲット出力形式でそのような並びを 伝えるためのエスケープシーケンスやコードへのマッピングを行う表を 持つことを要求されます。 *roff の世界へのコンバータでは、例えば "\xE9" (リテラルか E<...> 並びかに関わらず) は "e\\*'" として伝えられます。 同様に、Mac OS アプリケーションウィンドウに Pod をレンダリングする プログラムはおそらく "\xE9" を、(これを書いている時点では) Mac OS に ネイティブな MacRoman エンコーディングの部号位置 142 に マッピングされることを知っている必要があります。 このような「Unicode から何か」へのマッピングはおそらく一般的な 出力形式については既に広く利用可能です。 (このようなマッピングは不完全かも知れません! 実装者は、チェロキー音節、エルトリア語のルーン、ビザンツの音楽記号、 その他 Unicode がエンコード出来る変なものをレンダリングしようとして 最大の努力をすることを想定しません。) そして、Pod 文書がこのようなマッピングにない文字が使うと、 フォーマッタはこれをレンダリングできない文字として扱うべきです(should)。
もし、驚くべきことに、Pod フォーマッタの実装者が、Unicode 文字から ターゲット形式のエスケープへのマッピングに関する、満足できる既に存在する 表(例えば Unicode 文字から *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 にある文字表を 参照してください)の残りの注目するべき Unicode 文字と、あなたの 興味を引いたものなんでもに進んでください。 例えば、xhtml-symbol.ent には、以下のようなエントリがあります:
<!ENTITY infin "∞"> <!-- infinity, U+221E ISOtech -->
"infin" から文字 "\x{221E}" へのマッピングは(できれば)既に Pod パーサによって 扱われている一方、このファイルにこの文字があるということは、 注目すべき Unicode 文字からそれをレンダリングするために必要なコードへの マッピングを行うフォーマッタの表に含めることが十分に合理的なほど 重要であることを意味します。 それで、例えば Unicode-to-*roff のマッピングのためには、これはエントリに 値します:
"\x{221E}" => '\(in',
将来、より多くの形式(とフォーマッタ)が((X)HTML が ∞
, ∞
, ∞
で行うように) Unicode 文字を直接扱えるようになって、 Unicode-to-私のエスケープ への風変わりなマッピングの必要性が 減少することが熱望されています。
レンダリングできない文字(これは、レンダリング出来るかどうかに関わらず パーサが解決できない、不明な E<thing> 並びとは異なります)に 直面したときに良い判断を表示するのは個々の Pod 次第です。 ("E<eacute>"/"E<233>" のような)ダイアクリティカルマーク付きの Latin 文字を、(単純な文字 101, "e" のような)対応するアクセントなしの US-ASCII 文字にマッピングするのはよいプラクティスですが、明らかに これはしばしば実行不可能で、レンダリングできない文字は "?" のようなもので 表現されるかもしれません(may)。 (E<233> から "e" のような) 健全なフォールバックのために、 Pod フォーマッタは、もし利用可能なら Pod::Escapes または Text::Unidecode にある %Latin1Code_to_fallback テーブルを つかってもかまいません(may)。
例えば、以下の Pod 文章:
magic is enabled if you set C<$Currency> to 'E<euro>'.
は、以下のようにレンダリングされるでしょう: "magic is enabled if you set $Currency
to '?'" または "magic is enabled if you set $Currency
to '[euro]'" または "magic is enabled if you set $Currency
to '[x20AC]' など。
Pod フォーマッタは、レンダリングできない文字に出会ったときのリストを コメントや警告の形で記してもかまいません(may)。
E<...> は (他の E<...> および Z<> の中を除く) 任意の フォーマッティングコードの中に自由に現れてもかまいません(may)。 つまり、"X<The E<euro>1,000,000 Solution>" は、 "L<The E<euro>1,000,000 Solution|Million::Euros>" と同様 有効ということです。
Pod フォーマッタによっては、改行なし空白を独立した文字 (ここでは "NBSP" と呼ぶことにします) として実装しているフォーマットへ出力したり、 改行なし空白を「この線の場所で改行しない」コードでラップしている フォーマットに出力したりします。 Pod のレベルでは、どちらのコードもあり得ます: Pod は (リテラル、"E<160>"、"E<nbsp>"という形で) NBSP 文字を 含めることもできます; そして Pod は "S<foo I<bar> baz>" という コードを含むことができます; ここでそのようなコードでの「単なる空白」 (文字 32)は非分割空白を表現します。 Pod パーサは、"S<foo I<bar> baz>" を "fooNBSPI<bar>NBSPbaz" であるかのように、 また NBSP で連結された単語のグループを それぞれのグループが S<...> コードで囲まれているかのようにパースするオプションに 対応することを考慮するべきです(should); これによりフォーマッタは 出力形式が要求する最良のものにマッピングされる表現を使えるかもしれません。
一部のプロセッサは、S<...>
コードを最も簡単に実装するには S の内容のパース木の中にあるそれぞれの空白を NBSP に置き換えることで あることを発見するかもしれません。 しかし注意してください: 変換は 全て のテキストの空白では なく、 表示される テキストの空白 のみ に適用するべきです(should)。 (この区別は、その Pod パーサによって実装されている特定のツリー/イベント モデルによって明らかかもしれませんしそうではないかもしれません。) 例えば、次のような普通ではない場合を考えます:
S<L</Autoloaded Functions>>
これは、表示されるリンクテキストの途中にある空白は行をまたいではいけない (must not)ということです。 言い換えると、以下と同じです:
L<"AutoloadedE<160>Functions"/Autoloaded Functions>
しかし、空白から NBSP への変換を間違って適用すると、以下のようなものと 等価なものを(間違って)生成してしまうかもしれません:
L<"AutoloadedE<160>Functions"/AutoloadedE<160>Functions>
これはほぼ確実にハイパーリンクとしては動作しません (このフォーマッタが ハイパーテキストに対応した形式に出力すると仮定しています)。
フォーマッタは、単に S フォーマッティングコードに対応しないことを 選択してもかまいません(may); 特に出力形式に NBSP 文字/コードや 「この内容は行をまたがない」ためのコードがない場合です。
先に議論した NBSP 文字の他に、実装者は Latin-1 にその他の「特殊」文字の 存在を思い出させます; "soft hyphen" 文字、またの名を "discretionary hyphen"、例えば E<173>
= E<0xAD>
= E<shy>
) です。 この文字はオプションのハイフン位置を表現します。 これは、普通は何もレンダリングしませんが、フォーマッタがこの位置で 単語を分割したとき、"-" としてレンダリングされます。 Pod フォーマッタは、必要に応じて、次のうちどれか一つを 行うべきです(should): 1) これを同じ意味を持つコードとしてレンダリングする (例えば RTF の "\-" in 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" として 行うべき(should)であることを示します(そしてもし ハイフネーションしないなら、 E<shy>
は全く現れません)。 そして "Jarkko" や "Hietaniemi" をハイフネーションするときは、 E<shy>
コードがある場所でのみ行えます。
実際には、この文字はそう頻繁に使われないであろうと推測されますが、 フォーマッタはこれに対応するか、削除するかのどちらかをするべきです(should)。
Pod に (例えば "=biblio" コマンドのような) 新しいコマンドを追加したいと 考えているなら、同じ効果を for や begin/end の並びで得られないかどうかを 考慮してください: "=for biblio ..." または "=begin biblio" ... "=end biblio"。 "=for biblio" などを理解しない Pod プロセッサは単にこれを無視しますが、 "=biblio" を見つけると大声で警告を発生させるかもしれません。
この文書を通じて、"Pod" は文書フォーマットの名前として使われている 綴りです。 "POD" や "pod" を使う人もいるかもしれません。 (典型的には Pod 形式の文書では、"pod", "Pod", "POD" のいずれかを使えます。 これらの違いを理解することは有用です; しかしどう綴るかに捕らわれすぎるのは 普通は有用ではありません。
perlpod をちらっと見るだけでわかることは、L<...> コードは Pod フォーマッティングコードの中で最も複雑であると言うことです。 以下に示すポイントは、これが何を意味し、プロセッサがこれを どのように扱うべきかをできれば明確化しようとするものです。
L<...> コードをパースするときに、Pod パーサは少なくとも四つの 属性を区別しなければなりません(must):
リンクテキスト。 もしなければ、undef
でなければなりません(must)。 (例えば、"L<Perl Functions|perlfunc>" では、リンクテキストは "Perl Functions" です。 "L<Time::HiRes>" や、"L<|Time::HiRes>" でも、リンクテキストは ありません。 リンクテキストにはフォーマッティングコードを含んでいるかもしれないことに 注意してください。)
リンクテキストと推論されるもの; つまり、もし実際のリンクテキストが なければ、これはリンクテキストと推論されたものです。 (例えば、"L<Getopt::Std>" では、推論されたリンクテキストは "Getopt::Std" です。)
名前または URL (なければ undef
)。 (例えば、"L<Perl Functions|perlfunc>" では、名前 (また時々ページと 呼ばれるもの) は "perlfunc" です。 "L</CAVEATS>" では、名前は undef
です。)
章 (古い perlpod では「アイテム」と呼ばれていたもの)(なければ undef
)。 例えば、"L<Getopt::Std/DESCRIPTION>" では、"DESCRIPTION" が章です。 (これは "man 5 crontab" での "5" のような man ページの章と同じでは ないことに注意してください。 Pod での "○○の章" というのはテキストが "○○" である見出しや アイテムによって導入されるテキストの一部を意味します。)
また、Pod パーサは以下のような追加の属性に留意してもかまいません(may):
(もしあれば) 第三のアイテムが ("http://lists.perl.org" のような) URL かどうかを示すフラグ; この場合章の属性; はありません; ("perldoc" や "Getopt::Std" のような) Pod 名 ; ("crontab(5)" のような) man ページ名かもしれないものではありません。
"|", "/" などで分割したり 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 content
URL リンクは 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 the crontab(5)
manpage" あるいは単に "crontab(5)
" と レンダリングされます。
Pod プロセッサは "text|" の内リンクを以下のように 扱わなければなりません(must):
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>
フォーマッタはリンクを解決する目的でマークアップを無視して、 以下のようにセクション名としてレンダリング可能な文字だけを使うことを 選択してもかまいません(may):
<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 は "=headn Heading Content" コマンドまたは "=item Item Content" コマンドのどちらかを参照できるようになりました。 この仕様は、一つの文書に同じ section 識別子を出力するように見えるものが 複数ある場合 (例えば、HTML では、<a name="anchorname">...</a> で 同じ anchorname を生成するものが複数ある場合) の振る舞いは 規定していません。 Pod プロセッサがこの振る舞いを制御できるところでは、そのようなアンカーの 最初のものを使うべきです(should)。 つまり、L<Foo/Bar>
は Foo にある 最初の "Bar" を参照します。
しかし一部のプロセッサ/形式はこれは簡単には制御できません; HTML の例では、 複数の曖昧な <a name="anchorname">...</a> の振る舞いは、ブラウザが 決定するに任せるのがもっとも簡単です。
L<text|...>
コードは、以下のようにフォーマッティングや E<...> のためのフォーマッティングコードを含んでいてもかまいません(may):
L<B<ummE<234>stuff>|...>
"name|" 部分のない L<...>
コードでは、 E<...>
と Z<>
のコードのみ使ってもかまいません(may)。 つまり、著者は "L<B<Foo::Bar>>
" を使うべきではありません (should not)。
しかし、フォーマッティングコードと Z<> は L<...> の全ての部分 (つまり in name, section, text, url) に現れることに 注意してください。
著者は L<...> コードをネストさせてはいけません(must not)。 例えば、"L<The L<Foo::Bar> man page>" はエラーとして扱われるべきです (should)。
Pod 著者は "L<text|name>" (および L<text|/"sec">)の "text" 部分には フォーマッティングコードを使ってもかまわない(may)ことに注意してください。
言い換えると、次のものは有効です:
Go read L<the docs on C<$.>|perlvar/"$.">
"L<...>" コードをハイパーテキストとしてレンダリングする一部の出力形式は フォーマットされたリンクテキストを許さないかもしれません; この場合、フォーマッタは単にフォーマッティングを無視する必要があります。
これを書いている時点で、L<name>
の値は二つの種類があります: L<Foo::Bar>
のような Pod ページの名前 (@INC / PATH ディレクトリにある実際の Perl モジュールやプログラムかもしれませんし、 それらの場所にある .pod ファイルかもしれません); または L<crontab(5)>
のような Unix man ページの名前です。 理論的には、L<chmod>
は "chmod" という名前の Pod ページか "chmod" (man セクションのどこかにある) Unix man ページかがあいまいです。 しかし、"crontab(5)" のように、かっこの中に文字があるなら、対象となっている ものが Pod ページでないことを示すには十分なので、これはおそらく Unix man ページです。 区別は多くの Pod プロセッサにとっては重要ではありませんが、 ハイパーテキスト形式にレンダリングするプロセッサは、指定された L<foo>
コードをどのようにレンダリングするかを知るために これらを区別する必要があるかもしれません。
以前のバージョンの perlpod では(L<Object Attributes>
のような) L<section>
文法を許していました; これは L<name>
文法と簡単には区別できず、 L<"section">
とはほんの少しだけしか曖昧性が少なくなりません。 この文法は現在の仕様には含まれず、L</section>
文法で 置き換えられました(以前はスラッシュはオプションでした)。 Pod パーサは、少なくともしばらくの間は、L<"section">
文法を 許容するべきです(should)。 L<name>
を L<section>
と区別するための推奨される ヒューリスティックは、もし空白が含まれていれば、それは section と いうことです。 Pod プロセッサはこれらの廃止予定の文法に関して警告するべきです(should)。
"=over"..."=back" 領域は、様々な種類のリスト風の構造に使われます。 (ここでは、「領域」という用語は単に "=over" からそれに対応する "=back" までの全てを含むものという意味使っています。)
"=over indentlevel" ... "=back" での非ゼロ数値 indentlevel は、 フォーマッタに、いくつの「空白」(ems またはおよそ等価な単位) を 空けるべきかに関する手がかりを与えますが、多くのフォーマッタはこれを、 文書の基本フォントの空白 (あるいは M) のサイズと正確に一致しない 全体的な長さに変換する必要があります。 その他のフォーマッタは数値を完全に無視する必要があるかもしれません。 明示的な indentlevel パラメータがない場合、indentlevel の値が 4 の場合と等価です。 Pod プロセッサは、indentlevel が存在するけれども m/\A(\d*\.)?\d+\z/
にマッチングする正数ではない場合に警告を 出してもかまいません(may)。
Pod フォーマッタの作者は、"=over" ... "=back" は出力フォーマットによっては 複数の異なった構造に割り当てられるかもしれない(may)ことに留意してください。 例えば、Pod を (X)HTML に変換する場合、<ul>...</ul>, <ol>...</ol>, <dl>...</dl>, <blockquote>...</blockquote> のいずれかに 割り当てられるかもしれません。 同様に、"=item" は <li> または <dt> に割り当てられるかもしれません。
それぞれの "=over" ... "=back" 領域は以下のうちの一つであるべきです(should):
"=item *" 段落および、 通常の段落、そのままの段落、ネストした "=over" ... "=back" 領域、"=for..." 段落、"=begin"..."=end" コード のいずれかが任意の数引き続いたもののみからなる "=over" ... "=back" 領域。
(Pod プロセッサは、生の "=item" を、"=item *" であるかのように 扱わなければなりません(must)。) "*" をそのままアスタリスクとして表示するか、"o" を使うか、あるいは ある種の実際の黒丸を使うかは Pod フォーマッタに任されていて、 これはネストレベルに依存するかも知れません。
m/\A=item\s+\d+\.?\s*\z/
段落および、 通常の段落、そのままの段落、ネストした "=over" ... "=back" 領域、"=for..." 段落、"=begin"..."=end" コード のいずれかが任意の数引き続いたもののみからなる "=over" ... "=back" 領域。 各章の番号は 1 から始まり、省略されることなく続かなければならないことに 注意してください。
(Pod プロセッサは、"=item 1" のような行を、ピリオド付きの "=item 1." であるかのように扱わなければなりません(must)。)
"=item [text]" 段落および、 通常の段落、そのままの段落、ネストした "=over" ... "=back" 領域、"=for..." 段落、"=begin"..."=end" コード のいずれかが任意の数引き続いたもののみからなる "=over" ... "=back" 領域。
"=item [text]" 段落は、m/\A=item\s+\d+\.?\s*\z/
, m/\A=item\s+\*\s*\z/
にマッチングしたり、単に m/\A=item\s*\z/
にマッチングしたりするべきではありません(should not)。
"=item" 段落がまったくなく、いくつかの普通/そのままの段落と、 おそらくはいくつかのネストした "=over" ... "=back" 領域、"=for..." 段落、 "=begin"..."=end" 領域のみがある "=over" ... "=back" 領域。 Pod にあるこのような item なしの "=over" ... "=back" 領域は、HTML での "<blockquote>...</blockquote>" 要素と等価な意味を持ちます。
上述の全ての場合において、"=over" コマンドの後の ("=cut" と "=pod" を 除く) 最初の Pod 段落を調べることで、どの形式の "=over" ... "=back" であるかを決定できることに注意してください。
Pod フォーマッタは "=item text..." に任意の長さのテキストを 許容 しなければなりません (must)。 実際には、このような段落のほとんどは以下のような短いものです:
=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" コマンドを許容するべきです(should)。 中間の item が例です:
=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" 領域に見出しを含めることはできません。 プロセッサはそのような見出しをエラーとして扱ってもかまいません(may)。
"=over" ... "=back" 領域には内容があるべきであることに注意してください。 つまり、作者は以下のような空の領域を作るべきではありません:
=over
=back
Pod プロセッサがこのような、内容のない "=over" ... "=back" 領域を 発見した場合、無視してもかまいません(may)し、エラーとして 報告してもかまいません(may)。
プロセッサは、文書の末尾まで続く(つまり対応する "=back" がない) "=over" リストを許容しなければなりません(must)が、そのようなリストに 警告を出してもかまいません(may)。
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 は Pod 作者に上述の "=item" の 塊の構造を意味するようなグルーピングを区別する方法を提供しません。 従ってフォーマッタは以下のようにフォーマットするべきです(should):
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
つまり、(少なくともおおよそは)アイテム間の空白は段落間の空白と 同じであるべきです(should)(しかしこの空白はテキストの行の高さより 少なくてもかまいません(may))。 これにより、"Qui dolorem ipsum..." 段落が "Quisquam Est" アイテムのみと "Neque", "Porro", "Quisquam Est" の三つのアイテム全てのどちらに 掛かるのかを判断する文脈上の手がかりを使えるように読者に残しておきます。 理想的な状況ではありませんが、実際には著者の意図に反した フォーマッティングの手がかりを提供するよりは好ましいです。
データ段落は典型的には文書を特定のフォーマットでレンダリングするときに 使われる(典型的にはそのまま渡される)非 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</em>" を "E<lt>" や "E<eacute>" と同じように、 フォーマッティングコードとして展開しようとします。 しかし、これは "=begin identifier"..."=end identifier" 領域の 中にあり、かつ 識別子 "html" は ":" 接頭辞で始まっていないので、 この領域の内容は、通常の段落(あるいは、もしスペースやタブで 始まっている場合はそのままの段落)としてされるのではなく、データ段落として 保管されます。
さらなる例: これを書いている時点で、"biblio" 識別子には対応していませんが、 一部のプロセッサがこれを(例えば、必然的に通常の段落に フォーマッティングコードを含んでいる)参考文献を示すものとして認識する ように書かれているとします。 "biblio" 段落が通常通り処理されるということは、"biblio" 識別子にコロンが 付いていることで示されています:
=begin :biblio
Wirth, Niklaus. 1976. I<Algorithms + Data Structures =
Programs.> Prentice-Hall, Englewood Cliffs, NJ.
=end :biblio
これはパーサに、この begin...end 領域は普通の/そのままの段落として 通常通り扱われることを前提としていることを示します (一方 "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
しかし、"=begin identifier"..."=end identifier" 領域で identifier が コロンで始まって いない 場合、直接 "=head1" ... "=head4" コマンドや "=over", "=back","=item" を直接含むべきではありません(should not)。 例えば、以下のものは不正となります:
=begin somedata
This is a data paragraph.
=head1 Don't do this!
This is a data paragraph too.
=end somedata
Pod プロセッサは上述のようなもの (特に "=head1" 段落) をエラーとして 扱ってもかまいません(may)。 しかし、以下のようなものをエラーとして扱う べきではない (should not) ことに注意してください。
=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", and "=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 パーサは、(一つの領域に含まれた)連続したデータ段落を処理するときには、 たまたま空行を含んでいる一つの大きなデータ段落として考えるべきです(should)。 それで上述の "=begin html"..."=end html" の内容は二つのデータ段落 (一つは "<img src='wirth_spokesmodeling_book.png'>\n" で、もう一つは "<hr>\n") として保管しても かまいません が(may)、一つの大きな データ段落 ("<img src='wirth_spokesmodeling_book.png'>\n\n<hr>\n") として 保管される べき です(should)。
Pod プロセッサは 空の "=begin something"..."=end something" 領域、 空の "=begin :something"..."=end :something" 領域、中身のない "=for something" 段落と "=for :something" 段落を 許容するべきです(should)。 つまり、いかのようなものは許容されるべきです(should):
=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" コマンドが現れたとき、現在開いている領域のフォーマット名は "outer" ではなく "inner" なので、これは不適切です。 ("outer" はより高いレベルの領域のフォーマット名です。) これはエラーです。 プロセッサはデフォルトではこれをエラーと報告しなければならず(must)、 エラーを含む文書の処理を停止してもかまいません(may)。 ここから導かれる結論は、領域は「重複」できないということです。 つまり、上述の後者のブロックは X と Y を含む "outer" と呼ばれる領域と、 Y と Z を含む "inner" と呼ばれる重複した領域を表現しているわけではないと いうことです。 しかし、これは (明らかに重複している領域全てのように) 不正なので、 これは表現されなかったり、あるいはまったく表示されなかったりします。
同様に、以下のものも不正です:
=begin thing
=end hting
これは、領域が "thing" で開かれていて "=end" が "hting" (原文のまま) を 閉じようとしているので、エラーです。
また、以下のものも不正です:
=begin thing
=end
これは、全ての "=end" コマンドにはフォーマット名引数が必要なので、 不正です。
perlpod, "PODs: Embedded Documentation" in perlsyn, podchecker
Sean M. Burke