Spec-Zone.ru › Perl 5.34

perlpodspec

СОДЕРЖАНИЕ

  • ИМЯ
  • ОПИСАНИЕ
  • Определения Pod
  • Команды Pod
  • Коды форматирования Pod
  • Примечания по реализации обработчиков Pod
  • О кодах L<...>
  • О регионах =over...=back
  • О параграфах данных и регионах "=begin/=end"
  • СМОТРИТЕ ТАКЖЕ
  • АВТОР

ИМЯ

perlpodspec - Простое описание документации: спецификация формата и заметки

ОПИСАНИЕ

В этом документе содержатся подробные заметки о языке разметки Pod. Большинству пользователей достаточно прочитать perlpod, чтобы узнать, как писать на Pod, но этот документ может ответить на некоторые случайные вопросы, связанные с разбором и рендерингом Pod.

В данном документе термины «должен» / «не должен», «следует» / «не следует» и «может» имеют свои общепринятые значения (см. RFC 2119): «X должен сделать Y» означает, что если X не делает Y, это противоречит данной спецификации, и это нужно исправить. «X должен сделать Y» означает, что это рекомендуется, но X может не выполнить Y, если есть веская причина. «X может сделать Y» — это просто примечание, что X может сделать Y по своему желанию (хотя читатель должен определить, подразумевается ли «и я думаю, было бы хорошо, если бы X сделал Y» или «меня это не слишком беспокоит, если X сделал Y»).

Важно отметить, что когда я говорю «парсер должен сделать Y», парсер может не сделать Y, если вызывающее приложение явно запросило, чтобы парсер не делал Y. Часто я формулирую это как «парсер должен, по умолчанию, делать Y». Это не обязательно требует от парсера предоставить возможность отключения функции Y (например, расширения табуляции в параграфах verbatim), хотя это подразумевает, что такая возможность может быть предоставлена.

Определения Pod

Pod встроен в файлы, обычно в исходные файлы Perl, хотя вы можете написать файл, который состоит только из Pod.

Строка в файле состоит из нуля или более символов, отличных от новой строки, завершенных либо новой строкой, либо концом файла.

Последовательность новой строки обычно является платформозависимым понятием, но парсеры Pod должны понимать её как любой из CR (ASCII 13), LF (ASCII 10) или CRLF (ASCII 13, за которым сразу следует ASCII 10), помимо любых других специфичных для системы значений. Первая последовательность CR/CRLF/LF в файле может использоваться как основа для определения последовательности новой строки для разбора остальной части файла.

Пустая строка — это строка, состоящая только из нуля или более пробелов (ASCII 32) или табуляций (ASCII 9), завершенная новой строкой или концом файла. Непустая строка — это строка, содержащая один или более символов, отличных от пробела или табуляции (и завершенная новой строкой или концом файла).

(Примечание: Многие старые парсеры Pod не принимали строку, состоящую из пробелов/табуляций и новой строки, как пустую строку. Они считали пустой только строку, вообще не содержащую символов, завершенную новой строкой.)

Пробелы в этом документе используются как обобщающий термин для пробелов, табуляций и последовательностей новой строки. (Само по себе этот термин обычно относится к буквальным пробелам. То есть к последовательностям символов пробелов в исходном коде Pod, в отличие от «E<32>», который является кодом форматирования, обозначающим символ пробела.)

Парсер Pod — это модуль, предназначенный для разбора Pod (независимо от того, включает ли это вызов обратных вызовов или построение дерева разбора или непосредственного форматирования). Форматировщик Pod (или переводчик Pod) — это модуль или программа, которые преобразуют Pod в другой формат (HTML, обычный текст, TeX, PostScript, RTF). Обработчик Pod может быть форматировщиком или переводчиком, или может быть программой, выполняющей другие действия с Pod (например, подсчет слов, сканирование точек индексации и т. д.).

Содержание Pod содержится в блоках Pod. Блок Pod начинается со строки, соответствующей m/\A=[a-zA-Z]/, и продолжается до следующей строки, соответствующей m/\A=cut/, или до конца файла, если строки m/\A=cut/ нет.

Обратите внимание, что парсер не должен различать то, что похоже на под, но находится в строке с кавычками, например, в документе здесь.

Внутри блока Pod находятся абзацы Pod. Абзац Pod состоит из непустых строк текста, разделенных одной или несколькими пустыми строками.

Для целей обработки Pod существуют четыре типа абзацев в блоке Pod:

  • Параграф команды (также называемый «директивой»). Первая строка этого абзаца должна соответствовать 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;>?

    Другими словами, обработчик Pod для «head1» будет применять ту же обработку к «Вы помните, что нужно добавить C<use strict;>?» что и к обычному абзацу (т.е., коды форматирования, такие как «C<...>», анализируются и, предположительно, форматируются должным образом, а пробелы в виде буквальных пробелов и/или табуляций не имеют значения).

  • Абзац verbatim. Первая строка этого абзаца должна быть буквальным пробелом или табуляцией, и этот абзац не должен находиться внутри последовательности "=begin идентификатор", ... "=end идентификатор", если «идентификатор» не начинается с двоеточия (":"). То есть, если абзац начинается с буквального пробела или табуляции, но находится внутри области "=begin идентификатор", ... "=end идентификатор", то это параграф данных, если «идентификатор» не начинается с двоеточия.

    Пробелы имеют значение в параграфах verbatim (хотя, при обработке, табуляции, вероятно, будут расширены).

  • Обычный абзац. Абзац является обычным абзацем, если его первая строка не соответствует ни m/\A=[a-zA-Z]/, ни m/\A[ \t]/, и если он не находится внутри последовательности "=begin идентификатор", ... "=end идентификатор", если «идентификатор» не начинается с двоеточия (":").

  • Параграф данных. Это абзац, который находится внутри последовательности "=begin идентификатор" ... "=end идентификатор", где «идентификатор» не начинается с буквального двоеточия (":"). В некотором смысле, параграф данных не является частью Pod вообще (т.е., фактически он «вне зоны»), поскольку он не подлежит большинству видов обработки Pod; но он указан здесь, поскольку парсеры Pod должны иметь возможность вызывать событие для него или хранить его в каком-либо виде в дереве разбора, или, по крайней мере, просто анализировать вокруг него.

Например: рассмотрим следующие абзацы:

# <- that's the 0th column

=head1 Foo

Stuff

  $foo->bar

=cut

Здесь "=head1 Foo" и "=cut" являются параграфами команд, потому что первая строка каждого из них соответствует m/\A=[a-zA-Z]/. «[пробел][пробел]$foo->bar» — это параграф verbatim, потому что его первая строка начинается с буквального пробела (и нет области "=begin"..."=end").

Команды "=begin идентификатор" ... "=end идентификатор" препятствуют тому, чтобы абзацы, которые они окружают, анализировались как обычные или verbatim абзацы, если идентификатор не начинается с двоеточия. Это подробно обсуждается в разделе "О параграфах данных и регионах "=begin/=end".

Команды Pod

Этот раздел предназначен для дополнения и уточнения обсуждения в "Параграфе команды" в perlpod. Вот текущие распознаваемые команды Pod:

"=head1", "=head2", "=head3", "=head4"

Эта команда указывает, что текст в оставшейся части абзаца является заголовком. Этот текст может содержать коды форматирования. Примеры:

=head1 Object Attributes

=head3 What B<Not> to Do!
"=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.

Попытка начать блок Pod с команды "=cut" является ошибкой. В этом случае процессор Pod должен остановить разбор входного файла и по умолчанию выдать предупреждение.

"=over"

Эта команда указывает, что это начало области списка/отступа. Если после "=over" есть какой-либо текст, он должен состоять только из ненулевого положительного числового значения. Семантика этого числового значения объясняется в разделе "О регионах =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".

Рекомендуется, чтобы имена форматов соответствовали регулярному выражению m/\A:?[-a-zA-Z0-9_]+\z/. Всё, что следует за пробелом после имени формата, является параметром, который может использоваться форматировщиком при работе с этой областью. Этот параметр не должен повторяться в абзаце "=end". Разработчики должны учитывать возможность будущего расширения семантики и синтаксиса первого параметра для "=begin"/"=end"/"=for".

"=end formatname"

Это отмечает конец области, открытой соответствующим регионом "=begin formatname". Если "formatname" не является именем формата последнего открытого региона "=begin formatname", то это ошибка, и должно генерироваться сообщение об ошибке. Это подробно обсуждается в разделе "О абзацах данных и регионах "=begin/=end".

"=for formatname text..."

Это синоним:

=begin formatname

text...

=end formatname

То есть, он создаёт область, состоящую из одного абзаца; этот абзац будет обрабатываться как обычный абзац, если "formatname" начинается с двоеточия; если "formatname" не начинается с двоеточия, тогда "text..." будет составлять абзац данных. Нет способа использовать "=for formatname text..." для выражения "text..." как абзаца в оригинальном виде.

"=encoding encodingname"

Эта команда, которая должна появляться в начале документа (по крайней мере, до любых данных, отличных от US-ASCII!), объявляет, что этот документ закодирован в кодировке encodingname, которая должна быть именем кодировки, распознаваемым Encode. (Список поддерживаемых кодировок Encode, в Encode::Supported, здесь полезен.) Если анализатор Pod не может декодировать объявленную кодировку, он должен выдать предупреждение и может прервать разбор документа полностью.

Документ, имеющий более одной строки "=encoding", должен рассматриваться как ошибка. Процессоры Pod могут молчаливо терпеть это, если строки "=encoding", не являющиеся первой, просто дублируют первую (например, если есть строка "=encoding utf8", и позже ещё одна строка "=encoding utf8"). Но процессоры Pod должны жаловаться, если в одном документе есть противоречивые строки "=encoding" (например, если в начале документа есть "=encoding utf8" и "=encoding big5" позже). Процессоры Pod, распознающие BOM, также могут жаловаться, если они видят строку "=encoding", которая противоречит BOM (например, если у документа с BOM UTF-16LE есть строка "=encoding shiftjis").

Если процессор Pod видит любую другую команду, кроме перечисленных выше (например, "=head", или "=haed1", или "=stuff", или "=cuttlefish", или "=w123"), этот процессор по умолчанию должен рассматривать это как ошибку. Он не должен обрабатывать абзац, начинающийся с этой команды, должен по умолчанию предупреждать об этой ошибке и может прервать разбор. Парсер Pod может позволить определённым приложениям добавить в вышеупомянутый список известных команд и указать для каждой дополнительной команды, нужно ли обрабатывать коды форматирования.

В будущих версиях этого спецификации могут быть добавлены дополнительные команды.

Коды форматирования Pod

(Обратите внимание, что в предыдущих черновиках этого документа и perlpod коды форматирования назывались "внутренними последовательностями", и это понятие может всё ещё встречаться в документации по парсерам 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 особенно сложной частью является правильный разбор (возможно, вложенных!) кодов форматирования. Разработчики должны обратиться к коду в процедуре parse_text в Pod::Parser в качестве примера правильной реализации.

I<text> -- курсивный текст

См. краткое обсуждение в "Коды форматирования" в perlpod.

B<text> -- полужирный текст

См. краткое обсуждение в "Коды форматирования" в perlpod.

C<code> -- текст кода

См. краткое обсуждение в "Коды форматирования" в perlpod.

F<filename> -- стиль для имён файлов

См. краткое обсуждение в "Коды форматирования" в perlpod.

X<topic name> -- запись в индексе

См. краткое обсуждение в "Коды форматирования" в perlpod.

Этот код отличается от других, так как большинство форматировщиков полностью отбрасывают этот код и его содержимое. Другие форматировщики будут отображать его с невидимыми кодами, которые могут использоваться при построении индекса текущего документа.

Z<> -- пустой (нулевой эффект) код форматирования

Кратко обсуждается в "Коды форматирования" в perlpod.

Этот код отличается тем, что его содержимое должно отсутствовать. То есть, процессор может пожаловаться, если увидит Z<potatoes>. Будет ли он жаловаться или нет, текст картофель должен быть проигнорирован.

L<name> -- гиперссылка

Сложные синтаксисы этого кода подробно обсуждаются в "Коды форматирования" в perlpod, а подробности реализации обсуждаются ниже, в "О кодах L<...>". Разбор содержимого L<content> сложен. Отметим, что содержимое нужно проверить на то, выглядит ли оно как URL, или его нужно разделить по литералам "|" и/или "/" (в правильном порядке!), и так далее, до разрешения кодов E<...>.

E<escape> -- экранирование символа

См. "Коды форматирования" в perlpod и несколько пунктов в "Примечания по реализации процессоров Pod".

S<text> -- текст содержит неразрывные пробелы

Этот код форматирования прост в синтаксисе, но сложен в семантике. Его значение состоит в том, что каждый пробел в печатном содержимом этого кода обозначает неразрывный пробел.

Рассмотрим:

C<$x ? $y    :  $z>

S<C<$x ? $y     :  $z>>

Оба означают текст с моноширинным (стиль кода c[ode]) "$x", один пробел, "?", один пробел, ":", один пробел, "$z". Разница заключается в том, что во втором случае, с кодом S, эти пробелы являются не "обычными" пробелами, а неразрывными пробелами.

Если процессор Pod видит любой код форматирования, кроме перечисленных выше (например, "N<...>", или "Q<...>", и т.д.), этот процессор по умолчанию должен рассматривать это как ошибку. Парсер Pod может позволить определённым приложениям добавить в вышеупомянутый список известных кодов форматирования; парсер Pod даже может позволить указать для каждой дополнительной команды, требует ли она какой-либо особой обработки, как L<...>.

В будущих версиях этого спецификации могут быть добавлены дополнительные коды форматирования.

Историческая заметка: Некоторые старые процессоры Pod не распознавали ">" в качестве закрывающего символа для кода "C<", если ">" непосредственно предшествовал "-". Это позволяло так:

C<$foo->bar>

распознаваться эквивалентным так:

C<$foo-E<gt>bar>

а не как код форматирования "C", содержащий только "$foo-", а затем "bar>" за пределами кода форматирования "C". Эта проблема была решена добавлением синтаксисов, таких как этот:

C<< $foo->bar >>

Соответствующие парсеры не должны рассматривать "->" как специальный символ.

Коды форматирования категорически не могут охватывать абзацы. Если код открыт в одном абзаце, и закрывающий код не найден к концу этого абзаца, парсер Pod должен закрыть этот код форматирования и сообщить об ошибке (как в "Незакрытый код I в абзаце, начинающемся на строке 123: 'Объекты времени не...'"). Таким образом, эти два абзаца:

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

Следующий раздел содержит множество требований и рекомендаций, связанных с обработкой Pod.

  • Форматировщики Pod должны допускать строки в блоках verbatim любой длины, даже если это означает их разрыв (возможно, несколько раз для очень длинных строк), чтобы избежать выхода текста за пределы страницы. Форматировщики Pod могут предупреждать о таком разрыве строк. Такие предупреждения особенно уместны для строк, длина которых превышает 100 символов, что обычно не является преднамеренным.

  • Парсеры Pod должны распознавать все три известных формата новых строк: CR, LF и CRLF. См. perlport.

  • Парсеры Pod должны принимать входные строки любой длины.

  • Поскольку Perl распознаёт метку порядка байтов Unicode в начале файлов как сигнал о том, что файл закодирован в Unicode, как в UTF-16 (как big-endian, так и little-endian), или UTF-8, парсеры Pod должны делать то же самое. В противном случае кодировка символов должна пониматься как UTF-8, если последовательность первого байта с высоким битом в файле кажется допустимой как последовательность UTF-8, или в противном случае как CP-1252 (более ранние версии этого спецификации использовали Latin-1 вместо CP-1252).

    Будущие версии этого спецификации могут указать, как Pod может принимать другие кодировки. Предполагается, что обработка других кодировок в парсинге Pod будет такой же, как в парсинге XML: независимо от кодировки, объявленной конкретным файлом Pod, содержимое должно храниться в памяти в виде символов Unicode.

  • Известные метки порядка байтов Unicode следующие: если файл начинается с двух литеральных значений байтов 0xFE 0xFF, это BOM для big-endian UTF-16. Если файл начинается с двух литеральных значений байтов 0xFF 0xFE, это BOM для little-endian UTF-16. На платформе ASCII, если файл начинается с трёх литеральных значений байтов 0xEF 0xBB 0xBF, это BOM для UTF-8. Механизм, переносимый на платформы EBCDIC, это:

    my $utf8_bom = "\x{FEFF}";
    utf8::encode($utf8_bom);
  • Примитивный, но часто достаточный эвристический метод на платформах ASCII для проверки первой последовательности байта с высоким битом в файле без BOM (будь то в коде или в Pod!), чтобы определить, является ли эта последовательность допустимой как UTF-8 (RFC 2279), состоит в проверке того, что первый байт в последовательности находится в диапазоне 0xC2 - 0xFD и что следующий байт находится в диапазоне 0x80 - 0xBF. В этом случае парсер может заключить, что этот файл находится в формате UTF-8, и все последовательности байтов с высоким битом в файле должны рассматриваться как UTF-8. В противном случае парсер должен обработать файл как CP-1252. (Лучшая проверка, которая также работает на платформах EBCDIC, заключается в передаче копии последовательности в utf8::decode(), которая выполняет полную проверку валидности последовательности и возвращает TRUE, если она является допустимой UTF-8, и FALSE в противном случае. Эта функция всегда загружена предварительно, быстрая, потому что написана на C, и вызывается не более одного раза, поэтому вам не нужно избегать её по соображениям производительности.) В маловероятном случае, когда первая последовательность байтов с высоким битом в файле, который на самом деле не UTF-8, выглядит как UTF-8, можно учитывать наш эвристический метод (а также любой более умный эвристический метод) путём добавления к этой строке комментария, содержащего последовательность байтов с высоким битом, которая явно не является допустимой как UTF-8. Достаточно строки, состоящей просто из символа "#", острого е и любого байта без высокого бита, чтобы установить кодировку этого файла.

  • Обработчики 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 или dieing).

  • Парсеры Pod могут выводить предупреждения или сообщения об ошибках ("Неизвестный код E E<zslig>!") в STDERR (будь то путём печати в STDERR, или warning/carping, или dieing/croaking), но обязаны позволять подавление всех таких выводов в STDERR, а также предоставлять возможность сообщать об ошибках/предупреждениях каким-либо другим способом, будь то путём запуска обратного вызова, или обозначением ошибок в некотором атрибуте объекта документа или каким-либо аналогичным незаметным механизмом — или даже путём добавления раздела "Ошибки Pod" в конец проанализированной формы документа.

  • В случае чрезвычайно аномальных документов парсеры Pod могут прервать разбор. Даже тогда использование dieing/croaking следует избегать; где это возможно, библиотека парсера может просто закрыть входной файл и добавить текст, подобный "*** Разбор прерван ***" в конец (частичного) документа в памяти.

  • В абзацах, где понимаются форматирующие коды (например, E<...>, B<...>) (т.е., не абзацы verbatim, но включая обычные абзацы и абзацы команд, которые генерируют рендеримый текст, например, "=head1"), литеральные пробелы обычно считаются «незначимыми», причём один литеральный пробел имеет то же значение, что и любое (ненулевое) количество литеральных пробелов, литеральных новых строк и литеральных табуляций (при условии, что это не создаёт пустых строк, поскольку они завершают абзац). Парсеры Pod должны компактировать литеральные пробелы в каждом обработанном абзаце, но могут предоставить возможность для отмены этого (поскольку некоторые задачи обработки не требуют этого), или могут следовать дополнительным специальным правилам (например, специальной обработки последовательностей точка-пробел-пробел или точка-новая строка).

  • Парсеры Pod по умолчанию не должны пытаться преобразовать апострофы (') и кавычки (") в умные кавычки (маленькие 9', 66', 99' и т.д.), ни пытаться преобразовать обратную косую черту (`) во что-либо, кроме одного символа обратной косой черты (отличного от символа открывающей кавычки!), ни "--" во что-либо, кроме двух знаков минус. Они никогда не должны делать этого с текстом в кодах форматирования C<...> и никогда с текстом в абзацах verbatim.

  • При отображении Pod в формате, имеющем два вида дефисов (-), один неразрывный дефис, а другой разрывный дефис (как в «объектно-ориентированный», который можно разбить на строки как «объект-», новая строка, «ориентированный»), форматировщики рекомендуются в основном преобразовывать "-" в неразрывный дефис, но могут применять эвристику для преобразования некоторых из них в разрывные дефисы.

  • Форматировщики Pod должны прилагать разумные усилия, чтобы не разделять слова кода Perl на строки. Например, «Foo::Bar» в некоторых системах форматирования может рассматриваться как разрыв строки как «Foo::» новая строка «Bar» или даже «Foo::-» новая строка «Bar». Это следует избегать, по возможности, либо отключив весь разрыв строки внутри слова, либо обернув определённые слова с внутренней пунктуацией в коды «не разрывать эту строку» (которые в некоторых форматах могут не быть одним кодом, а могут представлять собой вставку неразрывных нулевых ширины пробелов между каждой парой символов в слове.)

  • Парсеры Pod по умолчанию должны расширять табуляции в абзацах verbatim при их обработке перед передачей их форматировщику или другому процессору. Парсеры также могут позволить возможность отмены этого.

  • Парсеры Pod по умолчанию должны удалять новые строки из конца обычных и verbatim абзацев перед передачей их форматировщику. Например, хотя абзац, который вы сейчас читаете, можно рассматривать в исходном коде Pod, как заканчивающийся (и содержащий) новые строки, которые его заканчивают, он должен обрабатываться как заканчивающийся (и содержащий) точкой, которая заканчивает это предложение.

  • При сообщении об ошибках парсеры Pod должны прилагать некоторые усилия для сообщения об приблизительном номере строки ("Вложенные E<>'s в абзаце #52, около строки 633 в файле Thing/Foo.pm!"), а не просто отмечать номер абзаца ("Вложенные E<>'s в абзаце #52 в файле Thing/Foo.pm!"). В проблемных случаях номер абзаца должен по крайней мере сопровождаться выдержкой из абзаца ("Вложенные E<>'s в абзаце #52 в файле Thing/Foo.pm, который начинается 'Read/write accessor for the C<interest rate> attribute...'").

  • При обработке серии абзацев verbatim друг за другом парсеры Pod должны рассматривать их как один большой абзац verbatim, который, случайно, содержит пустые строки. То есть эти две строки, имеющие пустую строку между ними:

    use Foo;
    
    print Foo->VERSION

    должны быть объединены в один абзац ("\tuse Foo;\n\n\tprint Foo->VERSION") перед передачей форматировщику или другому процессору. Парсеры также могут позволить возможность отмены этого.

    Хотя это может быть слишком громоздко для реализации в парсерах Pod на основе событий, это легко для парсеров, возвращающих деревья разбора.

  • Форматировщикам Pod, где это возможно, рекомендуется избегать разделения коротких абзацев verbatim (менее двенадцати строк) на страницы.

  • Парсеры Pod должны обрабатывать строку, содержащую только пробелы и/или табуляции, как «пустую строку», разделяющую абзацы. (Некоторые старые парсеры распознавали только две смежные новые строки как «пустую строку», но не распознавали новую строку, пробел и новую строку как пустую строку. Это не соответствующее спецификации поведение.)

  • Авторы форматировщиков/процессоров Pod должны прилагать все усилия для избегания написания собственного парсера Pod. Уже существует несколько в CPAN, с широким спектром стилей интерфейса — и один из них, Pod::Simple, поставляется с современными версиями Perl.

  • Символы в документах Pod могут передаваться либо как литералы, либо по номеру в кодах E<n>, либо с помощью эквивалентного мнемоника, как в E<eacute>, что точно эквивалентно E<233>. Числа — это значения Latin1/Unicode, даже на платформах EBCDIC.

    При ссылке на символы с использованием числового кода E<n>, числа в диапазоне 32-126 относятся к известным символам US-ASCII (также определённым в Unicode с тем же значением), которые все форматировщики Pod должны отображать точно. Символы, числовые коды E<> которых находятся в диапазонах 0-31 и 127-159, не должны использоваться (ни как литералы, ни как коды E<число>), за исключением литеральных последовательностей байтов для новой строки (ASCII 13, ASCII 13 10 или ASCII 10) и табуляции (ASCII 9).

    Числа в диапазоне 160-255 относятся к символам Latin-1 (также определённым в Unicode с тем же значением). Числа выше 255 должны пониматься как относящиеся к символам Unicode.

  • Будьте предупреждены, что некоторые форматировщики не могут надёжно отображать символы за пределами диапазона 32-126; многие из них могут обрабатывать диапазон 32-126 и 160-255, но ничего выше 255.

  • Помимо известных кодов «E<lt>» и «E<gt>» для символов «меньше» и «больше», парсеры Pod должны понимать код «E<sol>» для символа «/» (твёрдая черта, слэш) и «E<verbar>» для символа «|» (вертикальная черта, пайп). Парсеры Pod также должны понимать «E<lchevron>» и «E<rchevron>» как устаревшие коды для символов 171 и 187, то есть «левая двойная угловая кавычка» = «левая направленная угловая кавычка» и «правая двойная угловая кавычка» = «правая направленная угловая кавычка». (Эти символы похожи на маленькие «<<» и «>>», и их предпочтительно выражать с помощью HTML/XHTML-кодов «E<laquo>» и «E<raquo>».)

  • Парсеры Pod должны понимать все коды «E<html>», как определено в объявлениях сущностей в последней спецификации XHTML по адресу www.W3.org. Парсеры Pod должны понимать по крайней мере те сущности, которые определяют символы в диапазоне 160-255 (Latin-1). Столкнувшись с неизвестным кодом «E<идентификатор>», парсеры Pod не должны просто заменять его пустой строкой (по умолчанию, по крайней мере), но могут передавать его как строку, состоящую из символов E, меньше, идентификатор, больше. Или парсеры Pod могут предложить альтернативный вариант обработки таких неизвестных кодов «E<идентификатор>», вызывая событие специально для таких кодов или добавляя специальный тип узла в дерево документа в памяти. Такой код «E<идентификатор>» может иметь специальное значение для некоторых процессоров, или некоторые процессоры могут выбрать добавление их в специальный отчёт об ошибках.

  • Парсеры Pod также должны поддерживать XHTML-коды «E<quot>» для символа 34 (двойная кавычка, "), «E<amp>» для символа 38 (амперсанд, &) и «E<apos>» для символа 39 (апостроф, ').

  • Обратите внимание, что во всех случаях «E<что-то>», что-то (будь то html-имя или число в любой системе счисления) должно состоять только из буквенно-цифровых символов — то есть что-то должно соответствовать m/\A\w+\z/. Таким образом, «E< 0 1 2 3 >» недействителен, так как содержит пробелы, которые не являются буквенно-цифровыми символами. Вероятно, обработчик Pod не требует специального обращения с этим; « 0 1 2 3 » не выглядит как число в какой-либо системе счисления, поэтому он, вероятно, будет искомый в таблице HTML-подобных имён. Так как нет (и не может быть) HTML-подобной сущности, называемой « 0 1 2 3 », это будет рассматриваться как ошибка. Однако, обработчики Pod могут рассматривать «E< 0 1 2 3 >» или «E<e-acute>» как синтаксически недействительные, потенциально получая сообщение об ошибке, отличное от сообщения об ошибке (или предупреждение, или событие), сгенерированное просто неизвестным (но теоретически допустимым) html-именем, как в «E<qacute>» [sic]. Однако, парсеры Pod не обязаны делать это различие.

  • Обратите внимание, что E<число> не должно интерпретироваться как просто «код символа число в текущей/родной кодировке». Это всегда означает только «символ, представленный кодом символа число в Unicode». (Это идентично семантике &#число; в XML.)

    Это, вероятно, потребует от многих форматировщиков наличия таблиц, сопоставляющих обратимые коды Unicode (например, «\xE9» для символа e-acute) с последовательностями или кодами экранирования, необходимыми для передачи таких последовательностей в целевой формате вывода. Конвертер в *roff, например, знал бы, что «\xE9» (переданный буквально или через последовательность E<...>) должен быть передан как «e\\*'». Аналогично, программа, отображающая Pod в окне приложения Mac OS, вероятно, должна знать, что «\xE9» отображается кодом 142 в кодировке MacRoman, которая (на момент написания) является родной для Mac OS. Такие соответствия Unicode2whatever, вероятно, уже широко доступны для распространённых форматов вывода. (Эти соответствия могут быть неполными! От разработчиков не ожидается, что они будут прилагать неимоверные усилия для отображения символов чероки, этрусских рун, византийских музыкальных символов или других странных вещей, которые может кодировать Unicode.) И если документ Pod использует символ, отсутствующий в таком отображении, форматировщик должен рассматривать его как неотображаемый символ.

  • Если, к удивлению, разработчик форматировщика Pod не может найти удовлетворительную предварительно существующую таблицу отображения символов Unicode в последовательности экранирования целевого формата (например, приличная таблица символов Unicode в *roff-экранирования), потребуется создать такую таблицу. Если вы находитесь в этой ситуации, вы должны начать с символов в диапазоне 0x00A0 - 0x00FF, который в основном содержит часто используемые символы с диакритическими знаками. Затем продолжите (по мере возможности и необходимости) символами, которые группы стандартов (X)HTML посчитали достаточно важными, чтобы заслужить мнемонику. Они объявлены в спецификациях (X)HTML на сайте www.W3.org. На момент написания (сентябрь 2001 года) самые последние файлы объявления сущностей:

    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

    Затем вы можете продолжить работу с любыми оставшимися важными символами Unicode в диапазоне 0x2000-0x204D (см. таблицы символов на www.unicode.org) и чем-то ещё, что вам понравится. Например, в файле xhtml-symbol.ent есть запись:

    <!ENTITY infin    "&#8734;"> <!-- infinity, U+221E ISOtech -->

    Хотя сопоставление «infin» с символом «\x{221E}» (надеюсь) уже будет обработано парсером Pod, присутствие символа в этом файле означает, что он достаточно важен, чтобы включить его в таблицу форматировщика, сопоставляющую заметные символы Unicode с кодами, необходимыми для их отображения. Так, например, для соответствия Unicode-*roff это будет эквивалентно записи:

    "\x{221E}" => '\(in',

    С нетерпением ожидается, что в будущем всё больше форматов (и форматировщиков) будут поддерживать символы Unicode напрямую (как (X)HTML делает с &infin;, &#8734;, или &#x221E;), уменьшая необходимость специфичных отображений Unicode-в-my_escapes.

  • Каждый форматировщик Pod должен проявлять осмотрительность при столкновении с неотображаемым символом (что отличается от неизвестной последовательности E<что-то>, которую парсер не смог разрешить ни к чему, отображаемому или нет). Хорошей практикой является сопоставление латинских букв с диакритическими знаками (например, «E<eacute>»/«E<233>») с соответствующими безударными буквами US-ASCII (например, простым символом 101, «e»), но это часто не выполнимо, и неотображаемый символ может быть представлен как «?», или что-то подобное. При попытке разумного возврата (например, от E<233> к «e»), форматировщики Pod могут использовать таблицу %Latin1Code_to_fallback в Pod::Escapes или Text::Unidecode, если они доступны.

    Например, этот текст Pod:

    magic is enabled if you set C<$Currency> to 'E<euro>'.

    может быть представлен как: «магия включена, если вы установите $Currency в '?'» или как «магия включена, если вы установите $Currency в '[евро]'», или как «магия включена, если вы установите $Currency в '[x20AC]', и т. д.

    Форматировщик Pod также может отметить в комментарии или предупреждении список встреченных неотображаемых символов.

  • E<...> может свободно появляться в любом коде форматирования (кроме другого E<...> или Z<>). То есть, «X<Решение с E<евро>1 000 000>» допустимо, как и «L<Решение с E<евро>1 000 000|Million::Euros>».

  • Некоторые форматировщики Pod выводят в форматы, которые реализуют неразрывные пробелы как отдельный символ (который я буду называть «NBSP»), а другие выводят в форматы, которые реализуют неразрывные пробелы как пробелы, заключённые в код «не разрывать на строках». Обратите внимание, что на уровне Pod могут встречаться оба вида кодов: Pod может содержать символ NBSP (либо как литерал, либо как «E<160>» или «E<nbsp>»); и Pod может содержать коды «S<foo I<bar> baz>», где «простые пробелы» (символ 32) в таких кодах рассматриваются как неразрывные пробелы. Парсеры Pod должны учитывать возможность обработки «S<foo I<bar> baz>» так, как если бы это было «fooNBSPI<bar>NBSPbaz», и, в обратном направлении, возможность обработки групп слов, соединённых NBSP, как если бы каждая группа была в коде S<...>, чтобы форматировщики могли использовать представление, которое лучше всего соответствует требованиям выходного формата.

  • Некоторые процессоры могут обнаружить, что код S<...> проще всего реализовать, заменив каждый пробел в дереве разбора под содержимым S на NBSP. Но обратите внимание: замена должна применяться не ко всем пробелам, а только к пробелам в отображаемом тексте. (Это различие может или не может быть очевидным в конкретной модели дерева/события, реализованной парсером Pod.) Например, рассмотрим этот необычный случай:

    S<L</Autoloaded Functions>>

    Это означает, что пробел в середине текста видимой ссылки не должен разрываться на строках. Другими словами, это то же самое, что и это:

    L<"AutoloadedE<160>Functions"/Autoloaded Functions>

    Однако, неправильно применённая замена пробелов на NBSP может (неправильно) привести к чему-то, эквивалентному этому:

    L<"AutoloadedE<160>Functions"/AutoloadedE<160>Functions>

    ...что, почти наверняка, не будет работать как гиперссылка (предполагая, что этот форматировщик выводит формат, поддерживающий гипертекст).

    Форматировщики могут выбрать просто не поддерживать код формата S, особенно в тех случаях, когда выходной формат не имеет ни символа/кода NBSP, ни кода «не разрывать это на строках».

  • Помимо обсуждаемого выше символа NBSP, разработчикам напоминают о существовании другого «специального» символа в Latin-1 — символа «мягкий дефис», также известного как «условный дефис», т. е. 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-[перенос строки]action» или «manu-[перенос строки]script» (и если он не разбивает его, то E<shy> вообще не отображается). И если он должен разбить «Jarkko» и/или «Hietaniemi», он может сделать это только в тех местах, где есть код E<shy>.

    На практике ожидается, что этот символ не будет часто использоваться, но форматировщики должны либо поддерживать его, либо удалять.

  • Если вы думаете, что хотите добавить новую команду в Pod (например, команду "=biblio"), подумайте, можно ли получить тот же эффект с помощью последовательности for или begin/end: "=for biblio ..." или "=begin biblio" ... "=end biblio". Обработчики Pod, которые не понимают "=for biblio" и т. д., просто проигнорируют это, в то время как они могут громко пожаловаться, если увидят "=biblio".

  • На протяжении всего этого документа «Pod» использовалось как предпочтительное написание названия формата документации. Также можно использовать «POD» или «pod». Для документации, которая (обычно) находится в формате Pod, вы можете использовать «pod», «Pod» или «POD». Понимание этих различий полезно; но обычно не стоит зацикливаться на том, как их писать.

О кодах L<...>

Как видно из perlpod, код L<...> является наиболее сложным из кодов форматирования Pod. Ниже приведены пункты, которые, как надеются авторы, прояснят его значение и то, как процессоры должны с ним работать.

  • При разборе кода L<...> парсеры Pod должны различать как минимум четыре атрибута:

    Первый:

    Текст ссылки. Если его нет, это должно быть undef. (Например, в «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.)

    Четвертый:

    Раздел (также известный как «элемент» в более старых perlpods), или undef, если он отсутствует. Например, в «L<Getopt::Std/DESCRIPTION>» «DESCRIPTION» является разделом. (Обратите внимание, что это не то же самое, что раздел справки man, например, «5» в «man 5 crontab». «Раздел Foo» в смысле Pod означает часть текста, которая вводится заголовком или элементом, текст которого «Foo».)

    Парсеры Pod также могут отмечать дополнительные атрибуты, включая:

    Пятый:

    Флаг, указывающий, является ли элемент 3 (если он присутствует) URL-адресом (например, «http://lists.perl.org»), в этом случае атрибута раздела быть не должно; имя Pod (например, «perldoc» и «Getopt::Std»); или, возможно, имя страницы руководства man (например, «crontab(5)»).

    Шестой:

    Исходное содержимое L<...> в сыром виде, до разделения текста на «|», «/» и т. д., и до расширения кодов E<...>.

    (Вышеперечисленные пункты пронумерованы только для краткой ссылки ниже. Не требуется, чтобы эти пункты передавались в виде фактического списка или массива.)

    Например:

    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> им не является.

  • В случае кодов L<...> без части «текст|», более старые форматировщики демонстрировали значительные различия в фактическом отображении ссылки или перекрестной ссылки. Например, L<crontab(5)> отображался как «страница справки man crontab(5)», или «на странице справки man crontab(5)», или просто «crontab(5)».

    Теперь процессоры Pod должны обрабатывать ссылки без «текст|» следующим образом:

    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> ссылок (и их целей). Они были объединены синтаксически и семантически в текущем стандарте, и раздел может относиться как к команде "=headn Заголовок Содержимое", так и к команде "=item Элемент Содержимое". В данном стандарте не указано, как должно вести себя приложение в случае, если в документе есть несколько элементов, все кажущиеся одинаковыми идентификаторами раздела (например, в HTML, несколько элементов, все порождающих один и тот же имя_якоря в элементах <a name="имя_якоря">...</a>). В тех случаях, когда процессоры Pod могут контролировать это поведение, они должны использовать первый такой якорь. То есть, L<Foo/Bar> относится к первому разделу «Bar» в Foo.

    Однако для некоторых процессоров/форматов это невозможно легко контролировать; как в примере HTML, поведение нескольких неоднозначных <a name="имя_якоря">...</a> проще всего оставить на усмотрение браузеров.

  • В коде L<text|...> текст может содержать коды форматирования для форматирования или для экранирования E<...>, как в:

    L<B<ummE<234>stuff>|...>

    Для кодов L<...> без части «имя|» могут встречаться только коды E<...> и Z<>. То есть, авторы не должны использовать «L<B<Foo::Bar>>».

    Однако обратите внимание, что коды форматирования и Z<> могут встречаться в любой части L<...> (т. е. в имени, разделе, тексте и url).

    Авторы не должны вкладывать коды L<...>. Например, «L<Страница справки man L<Foo::Bar>>» должно обрабатываться как ошибка.

  • Обратите внимание, что авторы Pod могут использовать коды форматирования внутри части «текст» в «L<текст|имя>» (и так далее для L<текст|/"сек">).

    Другими словами, это допустимо:

    Go read L<the docs on C<$.>|perlvar/"$.">

    Некоторые форматы вывода, которые позволяют отображать коды «L<...>» в виде гипертекста, могут не позволять форматировать текст ссылки; в таком случае форматировщики должны просто игнорировать это форматирование.

  • На момент написания L<name> значения имеют два типа: либо имя страницы Pod, например L<Foo::Bar>, (что может быть реальным Perl-модулем или программой в каталогах @INC / PATH или файлом .pod в этих местах); или имя страницы справки Unix, например L<crontab(5)>. Теоретически, L<chmod> является неоднозначным как между страницей Pod под названием «chmod», так и страницей справки Unix «chmod» (в любом разделе справки man). Однако наличие строки в скобках, как в «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

"=over"..."=back" области используются для различных видов спископодобных структур. (Я использую термин «область» здесь просто как общее название всего от "=over" до соответствующего "=back".)

  • Ненольвое числовое значение indentlevel в "=over indentlevel" ... "=back" используется для подсказки форматировщику, сколько "пробелов" (ems или приблизительно эквивалентных единиц) следует отступать, хотя многие форматировщики должны преобразовать это в абсолютное значение, которое может неточно совпадать с размером пробелов (или букв М) в базовом шрифте документа. Другие форматировщики могут вообще проигнорировать это число. Отсутствие явного параметра indentlevel эквивалентно значению indentlevel равным 4. Обработчики Pod могут выдать ошибку, если indentlevel указан, но не является положительным числом, соответствующим m/\A(\d*\.)?\d+\z/.

  • Авторам форматировщиков Pod напоминается, что "=over" ... "=back" может отображаться в различных конструкциях выходного формата. Например, при преобразовании Pod в (X)HTML он может отображаться как <ul>...</ul>, <ol>...</ol>, <dl>...</dl> или <blockquote>...</blockquote>. Аналогично, "=item" может отображаться как <li> или <dt>.

  • Каждая область "=over" ... "=back" должна быть одной из следующих:

    • Область "=over" ... "=back", содержащая только команды "=item *", каждая из которых сопровождается некоторым количеством обычных/verbatim абзацев, другими вложенными областями "=over" ... "=back", абзацами "=for...", и областями "=begin"..."=end".

      (Обработчики Pod должны обрабатывать "пустой" "=item" так, как если бы это было "=item *".). То, отображается ли "*" как буква "звезда", буква "о" или какой-то реальный символ-маркер, зависит от форматировщика Pod и может зависеть от уровня вложенности.

    • Область "=over" ... "=back", содержащая только m/\A=item\s+\d+\.?\s*\z/ абзацы, каждый из которых (или каждая группа которых) сопровождается некоторым количеством обычных/verbatim абзацев, другими вложенными областями "=over" ... "=back", абзацами "=for..." и/или кодами "=begin"..."=end". Обратите внимание, что номера должны начинаться с 1 в каждом разделе, и должны следовать в порядке, не пропускают номера.

      (Обработчики Pod должны обрабатывать строки типа "=item 1" так, как если бы это было "=item 1.", с точкой.)

    • Область "=over" ... "=back", содержащая только команды "=item [текст]", каждая из которых (или каждая группа которых) сопровождается некоторым количеством обычных/verbatim абзацев, другими вложенными областями "=over" ... "=back" или абзацами "=for...", и областями "=begin"..."=end".

      Абзац "=item [текст]" не должен соответствовать m/\A=item\s+\d+\.?\s*\z/ или m/\A=item\s+\*\s*\z/, а также он не должен соответствовать только m/\A=item\s*\z/.

    • Область "=over" ... "=back", не содержащая вообще никаких команд "=item", и содержащая только некоторое количество обычных/verbatim абзацев, а также, возможно, некоторые вложенные области "=over" ... "=back", абзацы "=for..." и области "=begin"..."=end". Такая область "=over" ... "=back" без элементов "=item" в Pod эквивалентна элементу <blockquote>...</blockquote> в HTML.

    Обратите внимание, что во всех вышеперечисленных случаях вы можете определить, какой тип "=over" ... "=back" у вас есть, проверив первый (не "=cut", не "=pod") абзац Pod после команды "=over".

  • Форматировщики Pod должны обрабатывать произвольно большие объемы текста в абзаце "=item текст...". На практике большинство таких абзацев короткие, как в:

    =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 число" без сопровождающего абзаца. Средний элемент является примером:

    =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" не может содержать заголовки. Обработчики могут рассматривать такой заголовок как ошибку.

  • Обратите внимание, что область "=over" ... "=back" должна иметь какое-то содержимое. То есть, авторы не должны иметь пустую область подобную этой:

    =over
    
    =back

    Обработчики Pod, встретив такие пустые области "=over" ... "=back", могут проигнорировать их или могут сообщить об ошибке.

  • Обработчики должны обрабатывать список "=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 не предоставляет авторам 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"

Абзацы данных обычно используются для встраивания не-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 идентификатор"..."=end идентификатор" и идентификатор "html" не имеет префикса ":", содержимое этой области сохраняется как абзацы данных, вместо того, чтобы обрабатываться как обычные абзацы (или, если они начинаются с пробелов и/или табуляций, как verbatim-абзацы).

Ещё один пример: На момент написания не поддерживается идентификатор "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" как идентификатор цели и отметить отсутствие префикса ":".

Обратите внимание, что область "=begin идентификатор"..."=end идентификатор", где идентификатор начинается с двоеточия, может содержать команды. Например:

=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 идентификатор"..."=end идентификатор", где идентификатор не начинается с двоеточия, не должна непосредственно содержать команды "=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" может храниться как два абзаца данных (один состоящий из "<img src='wirth_spokesmodeling_book.png'>\n" и другой из "<hr>\n"), но должен храниться как один абзац данных (состоящий из "<img src='wirth_spokesmodeling_book.png'>\n\n<hr>\n").

Обработчики Pod должны обрабатывать пустые области "=begin что-то"..."=end что-то", пустые области "=begin :что-то"..."=end :что-то" и пустые абзацы "=for что-то" и "=for :что-то". То есть, это должно быть обработано:

=for html

=begin html

=end html

=begin :biblio

=end :biblio

Кстати, нет простого способа выразить абзац данных, начинающийся с чего-то, что выглядит как команда. Рассмотрите:

=begin stuff

=shazbot

=end stuff

Там "=shazbot" будет обработана как команда Pod "shazbot", а не как абзац данных "=shazbot\n". Однако вы можете выразить абзац данных, состоящий из "=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", текущая открытая область имеет имя формата "inner", а не "outer". (Просто так получается, что "outer" — это имя формата области выше.) Это ошибка. Обработчики по умолчанию должны сообщать об этом как об ошибке и могут остановить обработку документа, содержащего эту ошибку. Следствием этого является то, что области не могут "перекрываться". То есть, приведенный выше фрагмент кода не представляет область с именем "outer", содержащую X и Y, перекрывающую область с именем "inner", содержащую Y и Z. Но поскольку он недействителен (как и все, по-видимому, перекрывающиеся области), он ничего не представляет.

Аналогично, это недействительно:

=begin thing

=end hting

Это ошибка, потому что область открывается командой "thing", а "=end" пытается закрыть "hting" [sic].

Это также недействительно:

=begin thing

=end

Это недействительно, потому что каждая команда "=end" должна иметь параметр formatname.

СМОТРИТЕ ТАКЖЕ

perlpod, "PODs: Встроенная документация" в perlsyn, podchecker

АВТОР

Sean M. Burke

© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.34.0/perlpodspec

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API