Spec-Zone.ru › Perl 5.36

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, но находится в строке с кавычками, например, в документе here.

Внутри блока 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" применит ту же обработку к "Did You Remember to 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", "=head5", "=head6"

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

=head1 Object Attributes

=head3 What B<Not> to Do!

Оба =head5 и =head6 были добавлены в 2020 году и могут не поддерживаться всеми парсерами Pod. Pod::Simple 3.41 был выпущен в октябре 2020 года и поддерживает оба этих элемента, обеспечивая поддержку всех парсеров Pod, основанных на Pod::Simple.

"=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".

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

"=end formatname"

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

"=for formatname text..."

Это синонимично:

=begin formatname

text...

=end formatname

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

"=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> -- 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 распознает метку порядка байтов Юникода в начале файлов как указание на то, что файл закодирован в Юникоде как UTF-16 (в формате с большой или малой эндианностью) или UTF-8, парсеры Pod должны делать то же самое. В противном случае кодировка символов должна пониматься как UTF-8, если первая последовательность байтов с высоким битом в файле кажется допустимой как последовательность UTF-8, или в противном случае как CP-1252 (более ранние версии этого спецификации использовали Latin-1 вместо CP-1252).

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

  • Хорошо известные метки порядка байтов Юникода следующие: если файл начинается с двух буквальных байтовых значений 0xFE 0xFF, это BOM для UTF-16 в формате с большой эндианностью. Если файл начинается с двух буквальных байтовых значений 0xFF 0xFE, это BOM для 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. Строка, состоящая только из «#», острого e, и любого байта без высокого бита, достаточно для определения кодировки этого файла.

  • Обработчики 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, который начинается с 'Чтение/запись доступа к атрибуту C<ставка>...'»).

  • При обработке последовательности абзацев 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<number>), за исключением буквальных последовательностей байтов для перевода строки (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>" для «|» (вертикальная черта, pipe). Парсеры 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). Парсеры Pod, столкнувшись с неизвестным кодом "E<идентификатор>", не должны просто заменять его на пустую строку (по крайней мере, по умолчанию), но могут пропускать его как строку, состоящую из символов 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<число> не должен интерпретироваться как просто «кодовый символ число в текущей/нативной кодировке». Он всегда означает только «символ, представленный кодовым символом число в Юникоде». (Это идентично семантике &#число; в XML.)

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

  • Если разработчик форматера Pod, к удивлению, не может найти удовлетворительную существующую таблицу соответствия от символов Юникода до кодов escape в целевом формате (например, хорошую таблицу соответствия символов Юникода к *roff escape), потребуется создать такую таблицу. Если вы столкнулись с такой ситуацией, вы должны начать с символов в диапазоне 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

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

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

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

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

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

  • Отдельные форматеры Pod должны проявлять разумное суждение при столкновении с неотображаемым символом (который отличается от неизвестной последовательности E<что-то>, которую парсер не смог разрешить ни к чему отображаемому, ни к неопределённому). Хорошей практикой является отображение латинских букв с диакритическими знаками (таких как "E<eacute>"/"E<233>") соответствующими буквенными символами 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 на '[euro]'», или как «магия включена, если вы установите $Currency на '[x20AC]', и т. д.».

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

  • E<...> может свободно появляться в любом формате кода (кроме другого E<...> или в Z<>). То есть, "X<Решение по E<euro>1 000 000>" допустимо, как и "L<Решение по E<euro>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". В смысле Pod «раздел Foo» означает часть текста, введённую заголовком или элементом, текст которого «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> относится к первому разделу «Бар» в Футболке.

    Но для некоторых процессоров/форматов это нельзя легко контролировать; как и в примере 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<текст|/"sec">).

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

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

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

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

Это также недопустимо:

=begin thing

=end

Это недопустимо, так как каждая команда «=end» должна иметь параметр formatname.

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

perlpod, "PODs: Embedded Documentation" в 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.36.0/perlpodspec

Spec-Zone.ru

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